非常简单的代表沉思

时间:2010-04-25 19:58:12

标签: c# delegates

有时候最简单的问题会让我越来越喜欢C / C ++和C#。

今天坐在公共汽车上沉思着我记得的代表们 阅读somwhere,你不需要在实例化时使用new关键字 新代表。

例如:

    public static void SomeMethod(string message)
    {
      ...
    }

    ...


   public delegate void TestDelgate(string message); //Define a delegate

    ...........

   //create a new instance ..METHOD 1
   TestDelgate t = new TestDelgate(SomeMethod);  

   //OR another way to create a new instance ..METHOD 2
   TestDelgate t = SomeMethod;   //create a new instance ..METHOD 2

所以今天的问题是

  1. 方法2中引发了什么。编译器是否将方法2扩展为方法1,因此编写TestDelgate t = SomeMethod;只是一个捷径 TestDelgate t = new TestDelgate(SomeMethod);或者是方法2存在的另一个原因

  2. 你们认为方法1或方法2的可读性更好吗(这是一个主观问题,但我只是想对stackoverflow的一般意见有一种不科学的感觉: - )

7 个答案:

答案 0 :(得分:4)

是的,方法2只是方法1的简写 - 至少在使用方法组的情况下。你也可以 使用:

TestDelegate t = new TestDelegate(someExistingDelegate);

允许方差(不仅仅是C#4的通用方差)并创建一个单独的委托......但这很少有用。

我个人选择2 ...方法组转换非常方便。特别是它使事件布线更简单:

button.Click += LoadDocument;

而不是

button.Click += new EventHander(LoadDocument);

后者只是有额外的毛茸茸 - 前者具有更好的信息密度。当您将委托作为方法参数传递时,这也很重要。例如,比较:

observable.Subscribe(new Action<string>(Console.WriteLine));

observable.Subscribe(Console.WriteLine);

除非您真正想要将方法组转换为哪种委托类型,否则我只使用隐式转换。

答案 1 :(得分:2)

引擎盖下,你的两种方法完全一样。只是编译器对你想要做的事情很聪明。这个小功能称为delegate inference,并在C#2.0中添加。

我认为你应该使用#2,并利用委托推理。它们编译为相同的IL,选项#2更短更简洁。阅读和理解代码的含义更容易,因为噪音更少。

此语法为also supported for events

答案 2 :(得分:1)

  1. 是的,它们被编译成同样的东西。

  2. 我更喜欢#2。只是因为它更短而且不那么笨拙。由于之前已定义,您已经知道它是TestDelegate。那么为什么要再写一次呢?

答案 3 :(得分:1)

  1. 它只是显式委托创建的合成糖。这是C#2.0中的introduced。您可能已经注意到,如果要求Visual Studio 2008创建事件处理程序,它仍然会生成旧式(方法1)语法;我总是用新语法手动替换它。

  2. 我通常更喜欢方法2中的较短形式。我只使用方法1一次:使用从本机代码调用的委托,因此无法进行垃圾收集。我想非常明确地创建和分配它。

答案 4 :(得分:1)

是糖。当你不得不写这个时,真正派上用场的那种糖:

 someObj.Test -= new TestDelegate(SomeMethod);

什么?您必须使用 new 关键字删除事件处理程序。是的你是。 VB.NET团队对此非常痛苦,他们决定采用完全不同的语法:

 RemoveHandler someObj.Test, AddressOf SomeMethod


即使上面的C#语句都是糖,真正的代码如下所示:

 someObj.Test.remove(new TestDelegate(this, SomeMethod));

其中“remove”是事件的访问者函数。并且“this”是初始化Delegate.Target属性所必需的。现在很明显,它实际上是一个方法调用,并且使用new关键字突然再次有意义。隐藏“this”也有一些缺点,事件订阅不会再阻止对象被垃圾收集。

答案 5 :(得分:0)

引擎盖下两个语句创建委托对象并将参数传递给ctor:方法的地址和对此的引用。第二是语法糖。

答案 6 :(得分:0)

'new'语法的一个优点是它通知程序员正在分配一个新对象;如果希望避免重复创建新的相同代表,可以将代表拉出到一个字段。我知道事实上,一个人可以使用一个代表订阅而另一个代表可以取消订阅,但对我来说感觉不对。存储到代理用于订阅的字段,然后使用相同的委托取消订阅感觉更干净。恕我直言,如果订阅行为会返回一个MethodInvoker,当被调用时,将取消订阅(在这种情况下,“事件”只是一个接受EventHandler并返回MethodInvoker的函数),但是那是不是.net事件如何运作。