开发者

public event EventHandler SomeEvent = delegate { };

I am kind of tired of having all this useless noise in my code:

private void RaiseSomeOtherEventIfItIsNotNull()
{
    if (this.SomeOtherEvent != null)
    {
        this.SomeOtherEvent(this, EventArgs.Empty);
    }
}

In 99.9% of the cases I don't care if someone attached to it or if it is null or not. Just raise the event! I really don't get it why the c# compiler makes me write all this noise.

So I though I could maybe declare an event like this:

public event EventHandler SomeOtherEvent = delegate { };

this would allow me to get rid of the useless null check and the useless Raise* Method. I could just always do:

this.SomeOtherEvent(this, EventArgs.Empty);

Now when I compare the standard approach with "my" approach in Lutz Röder's Reflector I see some signigicant differences. The compiler has overriden Add{} and Remove{}there is an extra static instance of the anonymous delegate:

[CompilerGenerated] 
private static EventHandler CS$<>9__CachedAnonymousMethodDelegate1;

and there is this:

.method private hidebysig static void <.ctor>b__0(object, class [mscorlib]System.EventArgs) cil managed
{
 开发者_运维问答   .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor()
    .maxstack 8
    L_0000: nop 
    L_0001: ret 
}

Now my question: Do you seen any issues or disadvantages in decalring events with a default initialization like this?


You've shown an extra method, but not the extra class. The extra method is fine, IMO - that's just representing the no-op handler. Not a problem.

An extra class is somewhat surprising, as is the idea that it's changing the add/remove behaviour... the compiler would always be creating add/remove methods for the event, as that's what makes it an event.

Personally I think this is fine - but an alternative would be to write extension methods, e.g.

public static void Raise<T>(this EventHandler<T> handler, object sender, T args)
    where T : EventArgs
{
    if (handler != null)
    {
        handler(sender, args);
    }
}

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

then just call

myEvent.Raise(this, args);

That will work for all EventHandler and EventHandler<T> events.


The convention used by microsoft is this :

Declare the event like this.

public event EventHandler<ChangedArgs> ItemChanged; 

Then create a calling method

protected virtual void OnItemChanged(ChangedArgs args) 
{
     var handler = ItemChanged; 

     if (handler != null) 
         handler(this, args);
}

This also is ThreadSafe and whenever to raise the event, simply call OnItemChanged


As far as I can tell, no, since these are no-op handlers (since the IL generates a nop and a ret instruction). Assigning an empty handler is pretty much the same as having none at all, i.e. you do nothing about that event.


I could be completely wrong (and if so, do tell me why, I'm curious too now), but maybe you need to declare the event delegate at class level?

public delegate void SomeEvent(object sender, EventArgs e); 

?

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜