2012-09-21 3 views
6

Delegaci multiemisji muszą mieć typ zwrotny pustki W przeciwnym razie spowoduje to zgłoszenie wyjątku.Delegaci multiemisji muszą mieć typ pustego miejsca. Czemu?

Chcę wiedzieć, jaki jest tego powód, a co jeśli wiele metod może mieć taki sam typ zwrotu, jak delegata?

+2

Czy możesz podać przykład miejsca, w którym zgłasza wyjątek? –

Odpowiedz

25

Przesłanka jest błędna; działa dobrze:

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

To jest delegat multiemisji z niezerowym wynikiem, działa poprawnie. Z konsoli można zobaczyć, że obie części zostały wykonane. Wynik elementu last jest zwracany. Możemy wykazać, że jest to prawda, delegat multicast:

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

i będzie napisać „Jestem multicast” nawet już po pierwszym wierszu (gdy istnieje tylko jeden sposób na liście).

Jeśli potrzebujesz większej kontroli nad poszczególnymi wynikami, a następnie użyć GetInvocationList():

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

który pozwala zobaczyć każdy pojedynczy wynik.

W terminologii IL:

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

to znaczy: Func<T> dziedziczy z MulticastDelegate. Zasadniczo, do wszystkich celów i celów, delegatów w .NET są delegatów multiemisji. You może być w stanie uzyskać delegata bez multiemisji w zarządzanym C++, nie wiem. Ale na pewno nie z C#.

+0

Eeeek. Czy to zawsze działa w ten sposób? Mogłem sobie wyobrażać ... – Jon

+0

@Jon z pamięci, która mogła być jedną z dużych zmian między .NET 1.0 a .NET 1.1 –

+0

dzięki Mark ... pomogło ... – samj28

5

Następująca odpowiedź jest niezgodna z rzeczywistością, ponieważ obecnie * można * mieć delegatów multiemisji z niezobowiązującym typem zwrotów (jury nadal nie sprawdza, czy tak było zawsze). Jednak odpowiada na pytanie "Dlaczego język może zabronić takim delegatom?", Więc zostawiam to dla kompletności.

Teraz idź i prowokuj Marc.


Ponieważ wiele metod by zwracać wiele wartości, więc co należy wartość jeden powrót delegata być wtedy? Oczywiście nie ma odpowiedzi, która byłaby satysfakcjonująca we wszystkich okolicznościach. Można argumentować, że delegat multicast powinny:

  • powrót wartość pierwszej metody w celu wywołania (ale IIRC zamówienie inwokacja jest nieokreślona, ​​tak jak to będzie działać?)
  • powrót wartość ostatniej metody , jak wyżej
  • zwraca pojedynczą, odrębną wartość zwróconą przez wszystkich delegatów; wyrzuć wyjątek, jeśli nie wszystkie zgadzają się na:
+0

Należy zauważyć, że * wszyscy * delegaci w .NET to delegaci multi-cast. –

+0

@ Daniel Hilgarth: Czy odwołujesz się do nazwy klasy i obsługiwanej przez nią funkcjonalności? Jeśli tak, to technicznie masz rację, ale "wszyscy delegaci są multicastami" pozostawia złe wrażenie. Oczywiście możesz * możesz * mieć delegatów z nieważnym typem zwrotów, a to musi być uzgodnione z twoim oświadczeniem. – Jon

+0

Zobacz odpowiedź od Marca. Dokładnie to miałem na myśli. –

2

w multicast problemem jest to, że zastępują wszystkie wartości po prostu wydrukować ostatnią wartość metody, jeśli mają typ zwracany, więc trzeba uchwycić typ zwracanej jeden po drugim, pozwala zobaczyć kod poniżej

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(); ; 
    } 
}