Is calling an extension method on a “null” reference (i.e. event with no subscribers) evil?

前端 未结 8 714
梦谈多话
梦谈多话 2020-12-12 16:05

Evil or not evil?

public static void Raise(this EventHandler handler, object sender, EventArgs args)
{
   if (handler != null)
   {
      handler(sender, arg         


        
相关标签:
8条回答
  • 2020-12-12 16:30

    Not evil. I wish events worked this way by default. Can someone explain why an event with no subscribers is null?

    0 讨论(0)
  • 2020-12-12 16:33

    Don't forget to use [MethodImpl(MethodImplOptions.NoInlining)], else its possible that it isn't thread safe.

    (Read that somewhere long ago, remembered it, googled and found http://blog.quantumbitdesigns.com/tag/events/ )

    0 讨论(0)
  • 2020-12-12 16:41

    Although I wouldn't describ it as evil, it still has a negative implication, as it adds unnecessary overhead:

    When calling

    myEvent.Raise(this, new EventArgs());

    the object EventArgs is initialized in all situations, even if no-one subscribed to myEvent.

    When using

    if (myEvent!= null) {
       myEvent(this, new EventArgs());
    }
    

    EventArgs is only initialized if someone subscribed to myEvent.

    0 讨论(0)
  • 2020-12-12 16:43

    You can always declare your events like this (not that i recommend it):

    public event EventHandler<EventArgs> OnClicked = delegate { };
    

    That way they have something assigned to them when you call them, so they don't throw a null pointer exception.

    You can probably get rid of the delegate keyword in C# 3.0...

    0 讨论(0)
  • 2020-12-12 16:43

    Coming from a java background this has always seemed odd to me. I think that no one listening to an event is perfectly valid. Especially when listeners are added and removed dynamically.

    To me this seems one of C#'s gottchas that causes bugs when people don't know / forget to check for null every time.

    Hiding this implementation detail seems a good plan as it's not helping readability to check for nulls every single time. I'm sure the MSFTs will say there's a performance gain in not constucting the event if no one is listening, but imho it is vastly outweighed by the pointless null pointer exceptions / reduction in readability in most business code.

    I'd also add these two methods to the class:

        public static void Raise(this EventHandler handler, object sender)
        {
            Raise(handler, sender, EventArgs.Empty);
        }
    
        public static void Raise<TA>(this EventHandler<TA> handler, object sender, TA args)
            where TA : EventArgs
        {
            if (handler != null)
            {
                handler(sender, args);
            }
        }
    
    0 讨论(0)
  • 2020-12-12 16:47

    I wouldn't say it's evil, but I'm interested in how your extension method fits in with the

    protected virtual OnSomeEvent(EventArgs e){ }
    

    pattern and how it handles extensibility via inheritance. Does it presume all subclasses will handle the event instead of override a method?

    0 讨论(0)
提交回复
热议问题