Почему мое событие выдает нулевую ошибку?
По какой-то причине мое событие выдает нулевую ошибку. Я не вижу ничего плохого.
Вот событие
public delegate void connectionSuccess(bool success);
public event connectionSuccess Connection;
Тогда в функции у меня эта ведьма выбрасывает нулевую ошибку
Connection(true);
Edit * function в другом классе, который вызывает функцию соединения
Server.Connection += onConnection;
Server.startConnection();
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");
Надеюсь, что это кому-то поможет! Я проводил дни, пытаясь понять, почему мои события были нулевыми, когда я мог ясно видеть это. они были назначены!