Почему мое событие выдает нулевую ошибку? - PullRequest
2 голосов
/ 24 февраля 2012

По какой-то причине мое событие выдает нулевую ошибку.Я не вижу ничего плохого.

вот событие

public delegate void connectionSuccess(bool success);
public event connectionSuccess Connection;

тогда в функции, которая у меня есть, эта ведьма выдает нулевую ошибку

Connection(true);

Редактировать *функция в другом классе, которая вызывает функцию соединения

Server.Connection += onConnection;
Server.startConnection();

Ответы [ 5 ]

7 голосов
/ 24 февраля 2012

Если он не подключен, это null.

Попробуйте вместо этого:

var h = Connection;
if ( h!=null )
{
     h(true);
}

Сначала я назначаю (локальную) переменную, чтобы преодолеть-процедурные сценарии, в которых есть изменения между проверкой null и вызовом.

Т.е. следующее не будет поточно-ориентированным:

if ( Connection!=null )
{
    Connection(true);  // Here, could already be null, again.
}
0 голосов
/ 22 июля 2014

Вы должны проверить инициализацию ваших объектов. В то время как ваш код выглядит так, как будто все находится в одном классе, я не уверен, почему вам пришлось бы испытывать головную боль при создании событий, а не просто вызывать метод.

ОДНАКО, если вы поднимаете событие в одном классе и пытаетесь обработать его в другом, вы можете столкнуться с тем же, что и я. Позвольте мне объяснить ...

MDIParent - содержит код экземпляра для дочерней формы. Также имеется код для подключения обработчика событий дочернего элемента к коду на MDIParent.

Form x = new MyTestForm();
x.OnMyEvent += this.HandleEvent(myEventArgs);

MDIChild - содержит код, который мы используем для создания события и фактического его запуска.

public MyTestForm()
{
    public event EventHappened MyEventHandler;
}

Позже в коде мы фактически поднимаем событие.

MyEventHandler(new MyEventArgs(this, "some message");

Проблема, с которой я столкнулся во всех моих обработчиках событий, которые мы использовали для обновления StatusBar, заключалась в том, что подключение события не происходило до тех пор, пока форма не была полностью инициализирована. Это означает, что вся работа по настройке формы была завершена к тому времени, когда мы фактически связали событие с чем-либо!

Как я справился с этим, спросите вы? Ну, я переместил весь код инициализации в отдельный метод и из конструктора. Мы вызываем конструктор для создания экземпляра формы, связываем события и затем выполняем все задачи создания формы.

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

0 голосов
/ 24 февраля 2012

Вы получаете сообщение об ошибке, поскольку исключение нулевой ссылки будет выдано, если существует нулевая ссылка делегата ! Поэтому необходимо проверить ссылку на делегат.

Хорошей практикой является создание invocator event - вспомогательного метода. Это упрощает вызов обработчиков событий.

Например, давайте посмотрим на класс Book, который реализует интерфейс INotifyPropertyChanged:

class Book : INotifyPropertyChanged
{
    private string _name;
    public string Name
    {
        get { return _name; }
        set
        {
            if (_name == value)
                return;

            _name = value;
            OnPropertyChanged("Name");
        }
    }

    #region Implementation of INotifyPropertyChanged

    public event PropertyChangedEventHandler PropertyChanged;

    /// <summary>
    /// Event invocator.
    /// </summary>
    /// <param name="propertyName">Property name.</param>
    private void OnPropertyChanged(string propertyName)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
    }

    #endregion
}

Более подробная информация о реализации инвойсеров событий находится здесь: События и гонки .

0 голосов
/ 24 февраля 2012

Потому что у вас еще нет подписчиков.Когда событие не имеет подписчиков, оно становится null.У вас есть два варианта решения (я предпочитаю второй).

Вариант 1:

if (Connection != null)
    Connection(true);

Вариант 2:

public event connectionSuccess Connection = delegate { };
0 голосов
/ 24 февраля 2012

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

if(Connection != null)
    Connection(true);
...