+ = Delegate的运算符

时间:2015-11-27 21:20:52

标签: c# delegates

我知道 + = 运算符会将方法添加到由Delegate基础对象维护的调用列表中,例如

using System;

class Program
{

    delegate void MyDelegate(int n);

    void Foo(int n)
    {
        Console.WriteLine("n = {0}", n)
    }

    static void Main(string[] args)
    {
        MyDelegate d = new MyDelegate(Foo);
        d += Foo; // add Foo again

        d.Invoke(3); // Foo is invoked twice as Foo appears two times in invocation list

    }
}

但是,当我查看MSDN DelegateMulticastDelegate时,我无法找到 + = 运算符的任何定义。它是如何起作用的?自动生成编译器魔术?

2 个答案:

答案 0 :(得分:36)

它不是委托类型本身的运算符,用IL术语 - 它是在语言规范中定义的,但你不会使用反射找到它。编译器将其转换为对Delegate.Combine的调用。使用--=的反向操作使用Delegate.Remove

至少,这就是当C#以.NET为目标时的实现方式,因为它几乎总是如此。从理论上讲,这是特定于环境的 - 语言规范不要求编译器使用Delegate.CombineDelegate.Remove,而不同的环境可能没有这些方法。

从C#5规范,第7.8.4节(补充):

  

当两个操作数都属于某个委托类型+时,二进制D运算符会执行委托组合。 (如果操作数具有不同的委托类型,则会发生绑定时错误。)如果第一个操作数是null,则操作的结果是第二个操作数的值(即使它也是null })。否则,如果第二个操作数是null,则操作的结果是第一个操作数的值。否则,操作的结果是一个新的委托实例,在调用时,调用第一个操作数,然后调用第二个操作数。有关委托组合的示例,请参见§7.8.5和§15.4。由于System.Delegate不是委托类型,因此未为其定义运算符+

答案 1 :(得分:3)

Int32String等相同。+运算符由语言隐式定义。

您可以查看DelegateMulticastDelegateInt32等的源代码。operator +没有重载,这就是为什么它没有出现在MSDN文档。

从C#语言规范,第7.8.4节:

  

下面列出了预定义的附加运算符。

     

(...)

     

•代表组合。每个委托类型都隐式提供以下预定义运算符,其中D是委托类型:

     

D operator +(D x, D y);

简单类型和委托之间存在差异。 C#语言规范不要求使用System.Delegate

实现委托
  

4.2.7委托类型

     

委托是指引用一种或多种方法的数据结构。对于实例方法,它还引用它们对应的对象实例。   C或C ++中委托的最接近的等价物是函数指针,但是函数指针只能引用静态函数,委托可以引用静态和实例方法。在后一种情况下,委托不仅存储对方法入口点的引用,还存储对要调用该方法的对象实例的引用。   委托类型在§15中描述。

请注意,那里没有提到System.Delegate。将它与4.1.4简单类型进行比较:

  

C#提供了一组称为简单类型的预定义结构类型。简单类型通过保留字标识,但这些保留字只是System命名空间中预定义结构类型的别名,如下表所示。

     

保留字别名类型

     

sbyte System.SByte
  byte System.Byte
  简短的System.Int16
  ushort System.UInt16
  int System.Int32
  uint System.UInt32
  long System.Int64
  ulong System.UInt64
  char System.Char
  浮动System.Single
  double System.Double
  bool System.Boolean
  decimal System.Decimal

或4.2.4节字符串类型

  

(...)

     

关键字字符串只是预定义类System.String的别名。

因此,为Delegate.Combine的委托解析+运算符是.NET框架中C#编译器的实现细节。