+= operator for Delegate

2019-04-03 21:13发布

I know that the += operator will add a method to the invocation list maintained by the Delegate base object, for example

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

    }
}

But when I look at MSDN Delegate, MulticastDelegate I can't find any definition of the += operator. How is it that is just works? Auto-generated compiler magic?

标签: c# delegates
2条回答
可以哭但决不认输i
2楼-- · 2019-04-03 21:19

It's not an operator on the delegate type itself, in IL terms - it's defined in the language specification, but you wouldn't find it using reflection. The compiler turns it into a call to Delegate.Combine. The reverse operation, using - or -=, uses Delegate.Remove.

At least, that's how it's implemented when C# targets .NET, as it almost always does. In theory, this is environment-specific - the language specification doesn't require that a compiler uses Delegate.Combine or Delegate.Remove, and a different environment may not have those methods.

From the C# 5 specification, section 7.8.4 (addition):

The binary + operator performs delegate combination when both operands are of some delegate type D. (If the operands have different delegate types, a binding-time error occurs.) If the first operand is null, the result of the operation is the value of the second operand (even if that is also null). Otherwise, if the second operand is null, then the result of the operation is the value of the first operand. Otherwise, the result of the operation is a new delegate instance that, when invoked, invokes the first operand and then invokes the second operand. For examples of delegate combination, see §7.8.5 and §15.4. Since System.Delegate is not a delegate type, operator + is not defined for it.

查看更多
我只想做你的唯一
3楼-- · 2019-04-03 21:39

It's the same as with Int32, String etc. The + operator is defined implicitly by the language.

You can check the source code of Delegate, MulticastDelegate, Int32 etc. There are no overloads of operator + there, that's why it doesn't appear in the MSDN documentation.

From C# language spec, section 7.8.4:

The predefined addition operators are listed below.

(...)

• Delegate combination. Every delegate type implicitly provides the following predefined operator, where D is the delegate type:

D operator +(D x, D y);

There is a difference between simple types and delegates. The C# language specification doesn't require that a delegate is implemented using System.Delegate

4.2.7 Delegate types

A delegate is a data structure that refers to one or more methods. For instance methods, it also refers to their corresponding object instances. The closest equivalent of a delegate in C or C++ is a function pointer, but whereas a function pointer can only reference static functions, a delegate can reference both static and instance methods. In the latter case, the delegate stores not only a reference to the method’s entry point, but also a reference to the object instance on which to invoke the method. Delegate types are described in §15.

Note that there is no mention of System.Delegate there. Compare it with Section 4.1.4 Simple types:

C# provides a set of predefined struct types called the simple types. The simple types are identified through reserved words, but these reserved words are simply aliases for predefined struct types in the System namespace, as described in the table below.

Reserved word Aliased type

sbyte System.SByte
byte System.Byte
short System.Int16
ushort System.UInt16
int System.Int32
uint System.UInt32
long System.Int64
ulong System.UInt64
char System.Char
float System.Single
double System.Double
bool System.Boolean
decimal System.Decimal

Or Section 4.2.4 The string type

(...)

The keyword string is simply an alias for the predefined class System.String.

So resolving the + operator for delegates to Delegate.Combine is an implementation detail of C# compilers in .NET framework.

查看更多
登录 后发表回答