Обработчик событий был уже добавлен?

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

См. также: A хороший список лучших практик

Я бы добавил, очень важно, хорошо использовать модификатор final. Использование "окончательной" модификатор, когда это применимо в Java

Сводка:

  1. Используйте модификатор final для обеспечения хорошей инициализации.
  2. Избегайте возврата null в методы, например, при возврате пустых коллекций.
  3. Использовать аннотации @NotNull и @Nullable
  4. Быстрое завершение работы и использование утверждений, чтобы избежать распространения нулевых объектов через все приложение, когда они не должен быть пустым.
  5. Сначала используйте значения с известным объектом: if("knownObject".equals(unknownObject)
  6. Предпочитают valueOf() поверх toString ().
  7. Используйте null safe StringUtils StringUtils.isEmpty(null).

173
задан bdukes 23 November 2009 в 17:13
поделиться

5 ответов

Снаружи класса определения, как @Telos упоминания, можно только использовать EventHandler на левой стороне += или -=. Так, если у Вас есть способность изменить класс определения, Вы могли бы предоставить метод для выполнения проверки путем проверки, ли обработчик событий null - если так, то никакой обработчик событий не был добавлен. В противном случае тогда, возможно, и можно циклично выполниться через значения в Делегат. GetInvocationList. Если Вы равны делегату, которого Вы хотите добавить как обработчик событий, то Вы знаете, что это там.

public bool IsEventHandlerRegistered(Delegate prospectiveHandler)
{   
    if ( this.EventHandler != null )
    {
        foreach ( Delegate existingHandler in this.EventHandler.GetInvocationList() )
        {
            if ( existingHandler == prospectiveHandler )
            {
                return true;
            }
        }
    }
    return false;
}

И это могло легко быть изменено для становления, "добавьте обработчик, если это не там". Если у Вас нет доступа к внутренностям класса, это представляет событие, Вы, возможно, должны исследовать -= и +=, как предложил @Lou Franco.

Однако можно быть более обеспеченным повторным исследованием путем, Вы уполномочиваете и списываете эти объекты, чтобы видеть, не можете ли Вы найти способ отследить эту информацию сами.

119
ответ дан Blair Conrad 23 November 2019 в 20:36
поделиться

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

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

18
ответ дан Lou Franco 23 November 2019 в 20:36
поделиться

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

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

4
ответ дан George Stocker 23 November 2019 в 20:36
поделиться

Этот пример показывает, как использовать метод GetInvocationList () для получения делегатов во всех обработчиках, которые были добавлены. Если Вы надеетесь видеть, был ли определенный обработчик (функция) добавлен тогда, можно использовать массив.

public class MyClass
{
  event Action MyEvent;
}

...

MyClass myClass = new MyClass();
myClass.MyEvent += SomeFunction;

...

Action[] handlers = myClass.MyEvent.GetInvocationList(); //this will be an array of 1 in this example

Console.WriteLine(handlers[0].Method.Name);//prints the name of the method

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

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

6
ответ дан Jason Jackson 23 November 2019 в 20:36
поделиться
EventHandler.GetInvocationList().Length > 0
0
ответ дан Mariusz Jamro 23 November 2019 в 20:36
поделиться
Другие вопросы по тегам:

Похожие вопросы: