Почему мое событие выдает нулевую ошибку?


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

Вот событие

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

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

Connection(true);

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

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

5 ответов:

Если он не связан, то это null.

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

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

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

То есть следующее не будет потокобезопасным:

if ( Connection!=null )
{
    Connection(true);  // Here, could already be null, again.
}

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

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

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

Вариант 1:

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

Вариант 2:

public event connectionSuccess Connection = delegate { };

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

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

Например, давайте рассмотрим класс 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
}

Более подробная информация о реализации Event invocators есть здесь: события и расы .

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

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

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

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

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

public MyTestForm()
{
    public event EventHappened MyEventHandler;
}

Далее в коде мы фактически вызываем событие.

MyEventHandler(new MyEventArgs(this, "some message");
Проблема, с которой я столкнулся со всеми моими обработчиками событий, которые мы использовали для обновления строки состояния, заключалась в том, что подключение события не происходило до тех пор, пока форма не была полностью инициализирована. Это означает, что вся работа в настройка формы была завершена к тому времени, когда мы действительно связали событие с чем-то! Как мне удалось обойти это, спросите вы? Ну, я переместил весь код инициализации в отдельный метод и из конструктора. Мы вызываем конструктор для создания экземпляра формы, связываем события и затем выполняем все задачи создания формы.

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