+ =代表的运算符

我知道+ =运算符会将一个方法添加到由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 Delegate时 , MulticastDelegate我找不到+ =运算符的任何定义。 它是如何起作用的? 自动生成的编译魔术?

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

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

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

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

它与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
很长的System.Int64
ulong System.UInt64
char System.Char
float System.Single
double System.Double
bool System.Boolean
十进制System.Decimal

或4.2.4节字符串类型

(……)

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

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