【问题标题】:Is this a correct syntax for generic delegates and events?这是通用委托和事件的正确语法吗?
【发布时间】:2010-09-21 19:49:31
【问题描述】:

我正在阅读有关 genrics 的 msdn 库主题。有一个用泛型委托声明事件的例子,但它正确吗?

// 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> //Optional: 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?

我们可以直接将方法应用于事件,而不用我们的委托先包装它吗?

【问题讨论】:

  • 你的问题没有意义。没有委托就不能声明事件,无论它是否是通用的。
  • 你试过编译这个吗?这可能就是你的答案。
  • 这对我来说很好。它没有做你想做的事吗?
  • 我问为什么要声明最后一行:publisher.MyEvent +=subscriber.SomeMethod;,而不是 publisher.MyEvent += GenericEventHandler (subscriber.SomeMethod);

标签: c# events generics delegates


【解决方案1】:

是的,这是 C# 2.0 中的新功能,它将为您创建委托。请注意,您仍在创建委托,但创建是不可见的。

【讨论】:

  • 我没有看到任何特定于 C# 3 的内容...你在想哪一点?
  • publisher.MyEvent += subscriber.SomeMethod;
  • 这是一个方法组转换,来自 C# 2。
  • 哎呀,我总是把我的版本号弄糊涂了。它仍然是新的,因为没有代表的原始样式更新。
【解决方案2】:
publisher.MyEvent += subscriber.SomeMethod; 

在上一行中,右侧表达式“subscriber.SomeMethod”的类型为 GenericEventHandler(S sender,A args)。

就像对象是类类型的实例一样,方法也是委托类型的实例。 类指定对象的模板......委托指定方法的签名......即参数和返回类型。委托类型的变量只是对多个方法之一的引用,其签名符合委托声明中指定的方法。

在旧版本的 C# 中,您必须编写如下内容:

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

在较新版本的 C# 中,当您简单地提供subscriber.SomeMethod 时,会自动推断右侧那个长而丑陋的表达式的类型。它是由 SomeMethod 的签名以及 MyEvent 的类型推断出来的......这是指定签名的委托。

如果 SomeMethod 中的代码真的很琐碎,并且您不会从程序中的任何其他位置调用它,您可以完全避免将其编写为命名方法(如 SomeMethod),而是使用匿名方法语法如下并编写它那里然后:

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

                             };

或者更好的是,使用如下的 Lambda 表达式:

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

在上面的 lambda 表达式中,参数 's' 和 'a' 的类型是从 MyEvent 的类型自动推断出来的。 ...当然是指定签名的代表。

现在,只要 MyEvent 触发匿名方法中的代码或 lambda 表达式,就会执行。

【讨论】:

    【解决方案3】:

    我认为它称为委托推理。但无论它叫什么,它的使用都是完全合法的。它是在 c# 3.0 中添加的语法糖

    如果您需要了解通用代表和事件

    的工作原理,也许您应该使用它
    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();
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-07-11
      • 2011-03-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-09
      相关资源
      最近更新 更多