Почему публичное событие EventHandler cccc будет нулевым? - PullRequest
3 голосов
/ 17 июня 2010

Почему «публичное событие EventHandler cccc» будет нулевым?

У меня есть класс, который

public class Builder
{
    public event EventHandler StartedWorking;

    public Builder()
    { 
        // Constructor does some stuff
    }

    public void Start()
    {
       StartedWorking(this, eventargobject); //StartedWorking is null --
    }
}   

Это кажется простым и чем-то, что я делаю все время?Я упускаю что-то очевидное или есть что-то, что может вызвать это?

РЕДАКТИРОВАТЬ:

Означает ли это, что если я запустил событие, котороене подписан в клиентском классе, я должен проверить, что это не нуль?

РЕДАКТИРОВАТЬ-2:

Я думаю, я 'Я никогда не имел событий, на которые никогда не подписывался, и поэтому никогда не сталкивался с этим - Вы узнаете что-то новое каждый день. Извините за, казалось бы, глупый вопрос ...

Ответы [ 4 ]

12 голосов
/ 17 июня 2010

Обработчик события будет нулевым, если кто-то не подписан на событие. Как только делегат подписан на событие, он больше не будет иметь значение null.

Именно поэтому всегда предлагается использовать следующую форму для поднятия событий:

public void Start()
{
    var handler = this.StartedWorking;
    if (handler != null)
    {
         handler(this, eventArgObject);
    }
}

Это защитит вас от нулевого исключения, если подписчиков не было.

2 голосов
/ 17 июня 2010

Как уже говорили другие, это ноль, потому что нет подписчиков.

Чтобы ответить на ваши изменения: Да, вы всегда должны проверять событие на null, прежде чем запускать его. Однако, если вы просто наберете if(StartedWorking != null){...}, вы рискуете состоянием гонки, потому что подписчик может отказаться от подписки после нулевой проверки, но до того, как вы инициируете событие. Из-за этого вы всегда должны использовать этот шаблон при проверке событий на null:

protected void OnStartedWorking()
{
    EventHandler localEvent = StartedWorking
    if(localEvent != null)
    {
        localEvent(this, EventArgs.Empty);
    }
}

Это предотвращает состояние гонки, сначала беря копию события, поэтому список подписчиков фиксируется в точке копирования.

Существует больше информации о публикации событий в MSDN: Как публиковать события, соответствующие рекомендациям .NET Framework

(Это работает, потому что в .net класс MultiCastDelegate в imutable, поэтому любая попытка изменить список подписчиков в событии не повлияет на сделанную вами копию)

0 голосов
/ 17 июня 2010

Вам не нужно назначать функцию?

StartedWorking += new EventHandler(afunction);

void afunction(object sender, EventArgs e)
{
   DoSomething();
}
0 голосов
/ 17 июня 2010

Если вы не подключили подписчиков к вашему событию StartedWorking, тогда оно будет нулевым.Вот как работают события .NET.

Эта статья , помимо прочего, демонстрирует, что вы должны проверять наличие нуля, прежде чем вызывать событие. Этот другой вопрос и ответ демонстрирует, как вы можете создавать события таким образом, чтобы избежать нулевой проверки (в основном, всегда добавляя пустой обработчик).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...