2012-09-21 1 views
6

Multicast-Delegaten müssen den Rückgabetyp void haben Andernfalls wird eine Ausnahme ausgelöst.Multicast-Delegierte müssen den Rückgabetyp void haben. Warum?

Ich möchte wissen, was der Grund dahinter ist, was ist, wenn mehrere Methoden einen gleichen Rückgabetyp wie einen Delegaten haben könnten?

+2

Können Sie ein Beispiel dafür angeben, wo eine Ausnahme ausgelöst wird? –

Antwort

25

Die Prämisse ist falsch; es funktioniert gut:

Func<int> func = delegate { Console.WriteLine("first part"); return 5; }; 
func += delegate { Console.WriteLine("second part"); return 7; }; 
int result = func(); 

Das ist ein Multicast-Delegat mit einem non-void-Ergebnis, funktioniert gut. Sie können von der Konsole aus sehen, dass beide Teile ausgeführt wurden. Das Ergebnis des letzten Elements ist das zurückgegebene. Wir können zeigen, dass dies eine wahre Multicastdelegat ist:

if(func is MulticastDelegate) Console.WriteLine("I'm multicast"); 

und es wird schreiben: „Ich bin Multicast“ schon nach der ersten Zeile (wenn es nur eine einzige Methode aufgeführt).

Wenn Sie mehr Kontrolle über die einzelnen Ergebnisse benötigen, dann GetInvocationList() verwenden:

foreach (Func<int> part in func.GetInvocationList()) 
{ 
    int result = part(); 
} 

, die Sie jedes einzelne Ergebnis sehen können.

In IL Terminologie:

.class public auto ansi sealed Func<+ TResult> 
    extends System.MulticastDelegate` 

das heißt: Func<T> erbt von MulticastDelegate. Grundsätzlich sind Delegaten in .NET in allen Fällen Multicast-Delegaten. Sie möglicherweise in der Lage sein, einen nicht-Multicast-Delegaten in verwaltetem C++ zu bekommen, weiß ich nicht. Aber sicher nicht von C#.

+0

Eeeek. Hat es immer so funktioniert? Ich könnte mir vorstellen, Dinge ... – Jon

+0

@ Jon aus dem Speicher, das könnte eine der großen Änderungen zwischen .NET 1.0 und .NET 1.1 sein –

+0

Dank Mark ... es hat geholfen ... – samj28

5

Die folgende Antwort ist faktisch falsch, weil Sie * derzeit * Multicast-Delegierte mit nicht voidem Rückgabetyp haben können (die Jury ist noch nicht entschieden, ob dies schon immer so war). Es beantwortet jedoch die Frage "Warum könnte eine Sprache solche Delegierten verbieten?", Also überlasse ich es der Vollständigkeit.

Jetzt gehen und upvote Marc.


Da die mehrere Methoden mehrere Werte zurückgeben würde, so was sollte die einen Rückgabewert des Delegierten dann sein? Offensichtlich gibt es keine Antwort, die unter allen Umständen zufriedenstellend wäre. Man könnte argumentieren, dass die Multicastdelegat sollte:

  • Rückkehr der Wert des ersten Verfahrens in Aufruf Ordnung (aber IIRC Aufruf Auftrag ist nicht spezifiziert, so wie würde diese Arbeit?)
  • Rückkehr der Wert des letzten Verfahrens , wie oben
  • geben Sie den einzelnen eindeutigen Wert zurück, der von allen Delegaten zurückgegeben wird; eine Ausnahme auslösen, wenn nicht alle übereinstimmen
+0

Es muss angemerkt werden, dass * alle * Delegaten in .NET Multi-Cast-Delegaten sind. –

+0

@DanielHilgarth: Beziehen Sie sich auf den Klassennamen und die Funktionalität, die er unterstützt? Wenn ja, dann sind Sie technisch zwar richtig, aber "alle Teilnehmer sind Multicast" hinterlässt den falschen Eindruck. Offensichtlich können Sie * Delegierte mit nicht voidem Rückgabetyp haben, und dies muss mit Ihrer Aussage in Einklang gebracht werden. – Jon

+0

Siehe Antwort von Marc. Genau das meinte ich. –

2

in Multicast das Problem ist, dass es alle Werte außer Kraft setzen gerade die letzte Methode Wert drucken, wenn es Rückgabetyp haben, so dass Sie den Rückgabetyp einer nach dem anderen, zu erfassen haben können unter

den Code sehen
class Program 
{ 
    // i am going to add and subtract two num but i wanna get result in string the same thing you can do for int and what ever you want 
     delegate string mydeledagte(int a,int b); 
     delegate string d(int s, int t); 
    static void Main(string[] args) 
    { 
     mydeledagte ab = new mydeledagte(ad); 
     mydeledagte d= new mydeledagte(sub); 
     mydeledagte multi = ab + d; 

     foreach (mydeledagte individualMI in multi.GetInvocationList()) 
     { 
      string retVal = individualMI(3, 5); 
      Console.WriteLine("Output: " + retVal); 
      Console.WriteLine("\n***developer of KUST***"); 
      Console.ReadKey(); 
     } 
    } 
    static string ad(int a, int b) 
    { 

     return (a + b).ToString(); 

    } 
    static string sub(int a, int b) 
    { 

     return (a - b).ToString(); ; 
    } 
}