删除冗余的委托构造函数调用?

时间:2011-08-16 17:01:09

标签: c# events delegates resharper

我下载了ReSharper,它告诉我改变这一行:

dispMap.OnDraw += new EventHandler(dispMap_OnDraw);

成为这一行:

dispMap.OnDraw += dispMap_OnDraw;

因为第一行是“冗余委托构造函数调用。”

这是真的吗?在自动生成的表单设计器代码中,语法基于第一段代码,当键入dispMap.OnDraw +=并点击TAB时,IDE会自动生成new EventHandler(dispMap_OnDraw)

我只是对这个感到好奇。 ReSharper有意义吗?

4 个答案:

答案 0 :(得分:10)

是的,这是正确的。我在几个案例中做过这个。

委托构造函数调用应该是隐式的;该类型可以从OnDraw推断出来,并根据dispMap_OnDraw的方法签名进行验证。

此外,来自this MSDN article的引用似乎相关:

  

因为+ =运算符只是连接内部调用   一个委托给另一个委托的列表,你可以使用+ =来添加一个   匿名方法。请注意,使用匿名事件处理时,您不能   除非使用 - =运算符删除事件处理方法   通过首先将匿名方法存储到a中,将匿名方法添加为处理程序   委托然后在该事件中注册该代表。

我相信委托实例是以任一方式创建的,但由于在隐式实例化时没有委托的对象引用,因此无法使用-=运算符将其删除。

答案 1 :(得分:5)

确实有一点意义。第二行是第一行的简写。根据您的编码标准/惯例,您可以使用其中任何一个,但第一个确实会增加很多噪音。

答案 2 :(得分:3)

如果比较两种情况下生成的IL,您会发现它们是相同的。这是C#中的两种情况,以及它们导致的IL。

示例C#:

namespace EventTest
{
    public class Publisher
    {
        public delegate void SomeEvent(object sender);
        public event SomeEvent OnSomeEvent;
        public event SomeEvent OnOtherEvent;
    }

    public class Subscriber
    {
        public Subscriber(Publisher p)
        {
            p.OnSomeEvent += new Publisher.SomeEvent(Respond);
            p.OnOtherEvent += Respond;
        }

        public void Respond(object sender)
        {

        }
    }
}

这是构造函数的IL。请注意IL_000aIL_0028行。

.method public hidebysig specialname rtspecialname 
        instance void  .ctor(class EventTest.Publisher p) cil managed
{
  // Code size       48 (0x30)
  .maxstack  8
  IL_0000:  ldarg.0
  IL_0001:  call       instance void [mscorlib]System.Object::.ctor()
  IL_0006:  nop
  IL_0007:  nop
  IL_0008:  ldarg.1
  IL_0009:  ldarg.0
  IL_000a:  ldftn      instance void EventTest.Subscriber::Respond(object)
  IL_0010:  newobj     instance void EventTest.Publisher/SomeEvent::.ctor(object,
                                                                          native int)
  IL_0015:  callvirt   instance void EventTest.Publisher::add_OnSomeEvent(class EventTest.Publisher/SomeEvent)
  IL_001a:  nop
  IL_001b:  ldarg.1
  IL_001c:  ldarg.0
  IL_001d:  ldftn      instance void EventTest.Subscriber::Respond(object)
  IL_0023:  newobj     instance void EventTest.Publisher/SomeEvent::.ctor(object,
                                                                          native int)
  IL_0028:  callvirt   instance void EventTest.Publisher::add_OnOtherEvent(class EventTest.Publisher/SomeEvent)
  IL_002d:  nop
  IL_002e:  nop
  IL_002f:  ret
} 

结论:我认为没有任何理由改变您的代码,它们是等效的。

答案 3 :(得分:0)

它工作正常,我有DevExpress,它告诉我同样的事情!