开发者

Is this a correct syntax for generic delegates and events?

开发者 https://www.devze.com 2023-01-17 05:21 出处:网络
I\'m reading the msdn library topic about genrics . There is an example of declaring event wiht generic delegates, but is it correct?

I'm reading the msdn library topic about genrics . There is an example of declaring event wiht generic delegates, but is it correct?

// Code block 8. Generic event handling

public delegate void GenericEventHandler<S,A>(S sender,A args);
public class MyPublisher
{
   public event GenericEventHandler<MyPublisher,EventArgs> MyEvent;
   public void FireEvent()
   {
      MyEvent(this,EventArgs.Empty);
   }
}
public class MySubscriber<A> //Opt开发者_JAVA技巧ional: can be a specific type
{
   public void SomeMethod(MyPublisher sender,A args)
   {...}
}
MyPublisher publisher = new MyPublisher();
MySubscriber<EventArgs> subscriber = new MySubscriber<EventArgs>();
publisher.MyEvent += subscriber.SomeMethod;  // is this line correct?

Can we directly apply method to event, without wrapping it firstly with our delegate?


Yes, this is new functionality in C# 2.0 and it will create the delegate for you. Note that you are still creating a delegate, but the creation is invisible.


publisher.MyEvent += subscriber.SomeMethod; 

In the above line the the right hand side expression "subscriber.SomeMethod" has the type GenericEventHandler(S sender,A args).

Just as objects are instances of class types , methods are instances of delegate types. A class specifies the template for an object ... a delegate specifies the signature for a method.... that is parameter and return types. A variable of a delegate type is simply a reference to one of more methods whose signature complies with the one specified in the delegate declaration.

In the older versions of C# you would have to write something like the following :

publisher.MyEvent +=    
  new GenericEventHandler<MyPublisher,EventArgs>(subscriber.SomeMethod);

In the newer versions of C# , the type of that long ugly looking expression on the right hand side is automatically inferred when you simply provide subscriber.SomeMethod. And it is inferred by the signature of SomeMethod as well as the type of MyEvent ...which is the delegate specifying the signature.

If the code in SomeMethod is really trivial and you will not be calling it from any other place in the program you can totally avoid writing it in a named method (like SomeMethod) and instead use anonymous method syntax as following and write it there and then:

publisher.MyEvent += delegate(MyPublisher s, EventArgs a)
                             { 
                                 /* the SomeMethod Code */ 

                             };

Or even better, use Lambda expressions like following:

 publisher.MyEvent += (s, a) => {/*the SomeMethod code*/};

In the above lambda expression the types of the parameters 's' and 'a' are automatically inferred from the the type of MyEvent. ... which is ofcourse a delegate specifying the signature.

Now whenever the MyEvent fires the code in the anonymous method or the lambda expression will be executed.


I think its called Delegate Inference. But whatever its called its completely legal to use. Its a syntactically sugar added in c# 3.0

Maybe you should use this if you need to understand the working of Generic delegates and Events

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Generic_Delegates_and_Events
{
    public delegate void GenericEventHandler<S,A>(S sender,A args); //generic delegate

    public class MyPublisher
    {
        public event GenericEventHandler<MyPublisher,EventArgs> MyEvent;
        public void FireEvent()
        {
            MyEvent(this,EventArgs.Empty);
        }
    }

    public class MySubscriber<A> //Optional: can be a specific type
    {
        public void SomeMethod(MyPublisher sender,A args)
        {
            Console.WriteLine("MySubscriber::SomeMethod()");
        }
    }
    public class MySubscriber2<A> //Optional: can be a specific type
    {
        public void SomeMethod2(MyPublisher sender, A args)
        {
            Console.WriteLine("MySubscriber2::SomeMethod2()");
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            MyPublisher publisher = new MyPublisher();
            MySubscriber<EventArgs> subscriber = new MySubscriber<EventArgs>();
            publisher.MyEvent += subscriber.SomeMethod;
            MySubscriber2<EventArgs> subscriber2 = new MySubscriber2<EventArgs>();
            publisher.MyEvent += subscriber2.SomeMethod2;
            publisher.FireEvent();
        }
    }
}
0

精彩评论

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