2015-11-27 12 views
14

So che il + = operatore aggiungerà un metodo per la lista invocazione mantenuto dalla oggetto di base Delegato, per esempiooperatore + = per Delegato

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 

    } 
} 

Ma quando guardo MSDN Delegate, MulticastDelegate Non riesco a trovare alcuna definizione dell'operatore + =. Com'è che è solo un lavoro? Magia del compilatore generata automaticamente?

+1

Ho contrassegnato questo come un duplicato di [Perché non vedo l'operatore + = sovraccarico su System.Delegate?] (Http://stackoverflow.com/q/28391414/1364007) ma questa domanda ha (nel mio vista) risposte migliori. –

risposta

29

Non è un operatore sul tipo di delegato stesso, in termini IL - è definito nelle specifiche della lingua, ma non lo si troverà utilizzando la reflection. Il compilatore lo trasforma in una chiamata a Delegate.Combine. L'operazione inversa, utilizzando - o -=, utilizza Delegate.Remove.

Almeno, è così che viene implementato quando C# si rivolge a .NET, come quasi sempre. In teoria, questo è specifico per l'ambiente: le specifiche del linguaggio non richiedono che un compilatore usi Delegate.Combine o Delegate.Remove, e un ambiente diverso potrebbe non avere questi metodi.

Dalla # 5 specifica C, sezione 7.8.4 (aggiunta):

Il binario + operatore esegui delegare combinazione quando entrambi gli operandi sono di qualche tipo delegate D. (Se gli operandi hanno tipi di delegati diversi, si verifica un errore di tempo di binding.) Se il primo operando è null, il risultato dell'operazione è il valore del secondo operando (anche se è anche null). Altrimenti, se il secondo operando è null, il risultato dell'operazione è il valore del primo operando. Altrimenti, il risultato dell'operazione è una nuova istanza delegata che, invocata, richiama il primo operando e quindi richiama il secondo operando. Per esempi di combinazioni di delegati, vedere §7.8.5 e §15.4. Poiché System.Delegate non è un tipo delegato, l'operatore + non è definito per questo.

+0

Grazie, questo conferma cosa intendo per "compiler-magic", che il compilatore in qualche modo traduca il "+ =" in qualcosa che è definito e leggibile su MSDN. – jensa

+1

@jensa Se questa è la tua definizione di "compiler-magic" allora molte funzionalità sono magiche per il compilatore. Ad esempio '==' non è definito su System.Object ma la lingua definisce tale operatore. –

+0

@mikez: Penso che sia del tutto ragionevole fare una distinzione tra gli operatori specificati nella lingua - inclusa l'uguaglianza di riferimento '==' come si cita, e anche la concatenazione di stringhe - e quelle fornite dalla libreria, come 'DateTime + (DateTIme , Periodo) '. –

3

E 'lo stesso con Int32, String ecc L'operatore + è definito implicitamente dal linguaggio.

è possibile controllare il codice sorgente di Delegate, MulticastDelegate, Int32 ecc Ci sono sovraccarichi di operator + lì, è per questo che non appare nella documentazione di MSDN.

Dal linguaggio C# spec, sezione 7.8.4:

gli operatori di addizione predefiniti sono elencati di seguito.

(...)

• Delegate combinazione. Ogni tipo delegato fornisce implicitamente la seguente operatore predefinito, dove D è il tipo delegato:

D operator +(D x, D y);

C'è una differenza tra i tipi semplici e delegati.La specifica linguaggio C# non richiede che un delegato è implementato utilizzando System.Delegate

4.2.7 tipi delegato

Un delegato è una struttura dati che fa riferimento a uno o più metodi. Ad esempio, metodi si riferisce anche alle loro istanze oggetto corrispondenti. L'equivalente più vicino di un delegato in C o C++ è un puntatore a funzione, ma mentre un puntatore a funzione può solo fare riferimento a funzioni statiche, un delegato può fare riferimento sia ai metodi statici che a quelli di istanza. In quest'ultimo caso, il delegato memorizza non solo un riferimento al punto di ingresso del metodo, ma anche un riferimento all'istanza dell'oggetto su cui richiamare il metodo. I tipi di delegati sono descritti in §15.

Nota che non c'è menzione di System.Delegate lì. Confrontalo con Sezione 4.1.4 Tipi semplici:

C# fornisce un set di tipi di struct predefiniti chiamati tipi semplici. I tipi semplici sono identificati tramite parole riservate, ma queste parole riservate sono semplicemente alias per tipi di struct predefiniti nello spazio dei nomi System, come descritto nella tabella seguente.

Reserved parola Aliased tipo

sbyte System.SByte
byte System.Byte
breve System.Int16
ushort System.UInt16
int System.Int32
uint System.UInt32
lungo System.Int64
ulong System.UInt64
char System.Char
galleggiante System.Single
doppia System.Double
bool System.Boolean
decimale tipo System.Decimal

o sezione 4.2.4 La stringa

(...)

La stringa di parole chiave è semplicemente un alias per la classe predefinita System.String.

Quindi la risoluzione dell'operatore + per i delegati su Delegate.Combine è un dettaglio di implementazione dei compilatori C# in .NET framework.