События Raising C# с дополнительным методом - являются этим плохо?

Другое событие 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));
}

50
задан Bill Tarbell 18 July 2019 в 03:55
поделиться

4 ответа

Это будет все еще работать с событиями, которые имеют явное, добавляют/удаляют - просто необходимо использовать переменную делегата (или однако Вы сохранили делегата) вместо имени события.

Однако существует более легкий способ сделать, он ориентированный на многопотоковое исполнение - инициализирует его ни с каким-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": Вы - планирование Ваших классов, получаемых из? По моему мнению, большинство классов должно быть изолировано. Если Вы делаете , Вы хотите, чтобы те производные классы были в состоянии сгенерировать событие? Если ответ на любой из этих вопросов является "нет", тогда не беспокоятся. Если ответ обоим - "да", тогда сделайте:)

56
ответ дан Jon Skeet 7 November 2019 в 11:01
поделиться

[Вот мысль]

, Просто пишут код однажды рекомендуемым способом и делаются с ним. Тогда Вы не смутите своих коллег, просматривающих код, думая, что Вы сделали что-то не так?

[я прочитал больше сообщений, пытающихся находить способы вокруг записи обработчика событий, чем я когда-нибудь трачу запись обработчика событий.]

5
ответ дан Robert Paulson 7 November 2019 в 11:01
поделиться

Меньше кода, более читаемого. Я как.

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

public event EventHandler SomethingHappened = delegate{};
3
ответ дан Cristian Libardo 7 November 2019 в 11:01
поделиться

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

Вы сохраняете себя от исключения нулевой ссылки, но существуют более легкие способы сделать это как Jon Skeet и cristianlibardo, на который указывают в их ответах.

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

1
ответ дан Isak Savo 7 November 2019 в 11:01
поделиться