Другое событие NullPointerException
возникает, когда объявляется массив объектов, а затем сразу же пытается разыменовать его внутри.
String[] phrases = new String[10];
String keyPhrase = "Bird";
for(String phrase : phrases) {
System.out.println(phrase.equals(keyPhrase));
}
Этот конкретный NPE можно избежать, если порядок сравнения отменяется ; а именно, использовать .equals
для гарантированного непустого объекта.
Все элементы внутри массива инициализируются их общим начальным значением ; для любого типа массива объектов, это означает, что все элементы null
.
Вы должны инициализировать элементы в массиве перед доступом или разыменованием их.
String[] phrases = new String[] {"The bird", "A bird", "My bird", "Bird"};
String keyPhrase = "Bird";
for(String phrase : phrases) {
System.out.println(phrase.equals(keyPhrase));
}
Это будет все еще работать с событиями, которые имеют явное, добавляют/удаляют - просто необходимо использовать переменную делегата (или однако Вы сохранили делегата) вместо имени события.
Однако существует более легкий способ сделать, он ориентированный на многопотоковое исполнение - инициализирует его ни с каким-op обработчиком:
public event EventHandler SomethingHappened = delegate {};
хит производительности вызова дополнительного делегата будет незначителен, и это уверенный делает код легче.
Между прочим, в Вашем дополнительном методе Вам не нужна дополнительная локальная переменная - Вы могли просто сделать:
static public void RaiseEvent(this EventHandler @event, object sender, EventArgs e)
{
if (@event != null)
@event(sender, e);
}
static public void RaiseEvent<T>(this EventHandler<T> @event, object sender, T e)
where T : EventArgs
{
if (@event != null)
@event(sender, e);
}
Лично я не использовал бы ключевое слово в качестве названия параметра, но это действительно не изменяет сторону вызова вообще, сделайте то, что Вы хотите:)
РЕДАКТИРОВАНИЕ: Что касается метода "OnXXX": Вы - планирование Ваших классов, получаемых из? По моему мнению, большинство классов должно быть изолировано. Если Вы делаете , Вы хотите, чтобы те производные классы были в состоянии сгенерировать событие? Если ответ на любой из этих вопросов является "нет", тогда не беспокоятся. Если ответ обоим - "да", тогда сделайте:)
[Вот мысль]
, Просто пишут код однажды рекомендуемым способом и делаются с ним. Тогда Вы не смутите своих коллег, просматривающих код, думая, что Вы сделали что-то не так?
[я прочитал больше сообщений, пытающихся находить способы вокруг записи обработчика событий, чем я когда-нибудь трачу запись обработчика событий.]
Меньше кода, более читаемого. Я как.
, Если Вы не интересуетесь производительностью, можно объявить, что событие как это избегает пустой проверки:
public event EventHandler SomethingHappened = delegate{};
Вы не "обеспечение" потокобезопасность путем присвоения обработчика локальной переменной. Ваш метод мог все еще быть прерван после присвоения. Если, например, класс, который раньше прислушивался к событию, расположен во время прерывания, Вы называете метод в склонном классе.
Вы сохраняете себя от исключения нулевой ссылки, но существуют более легкие способы сделать это как Jon Skeet и cristianlibardo, на который указывают в их ответах.
Другая вещь состоит в том, что для незапечатанных классов, метод OnFoo должен быть виртуальным, который я не думаю, возможно с дополнительными методами.