2016-04-05 7 views
1

kann sagen, dass ich die nächste Kurs Klasse:Allgemein Delegattyp Fehler

class Course 
    { 
     internal Student myStudent { get; set; } 
     internal string Name { get; set; } 

     public override string ToString() 
     { 
      return string.Format("{0, -5} {1, -15} {2}", Name, myStudent.Name, string.Join(" ", myStudent.Grade)); 
     } 
     internal class Student 
     { 
      internal string Name { get; set; } 
      internal List<int?> Grade { get; set; } 
     } 
    } 

und ich möchte in der Hauptverwendung in einem generischen Delegaten, einmal für int und einmal für string:

SomeDelegate<string> d1 = new SomeDelegate<string>(course => course.Name); 
SomeDelegate<int> d2 = new SomeDelegate<int>(course => (int)course.myStudent.Grade.DefaultIfEmpty(null).Average()); 

Der generische Vertreter ist:

delegate T SomeDelegate<T>(T param); 

aber ich bekomme Fehler.

Zeichenfolge keine Definition für 'Name' enthält ....

Warum ist das so?

Danke!

+1

'T' ist sowohl die Art des Arguments und der Rückgabetyp des Delegaten, in 'd1' ist' course' also eine 'string' (und in' d2' ist es ein 'int'). Sie werden wahrscheinlich 'Func ' (und 'Func ') stattdessen verwenden. –

Antwort

4

Ihre Delegatendefinition erfordert, dass der Typ des Eingangsparameters und der Ausgang identisch sind. In Ihrem Fall versuchen Sie, ein Objekt mit einer Name-Eigenschaft zu übergeben und eine Zeichenfolge zurückzugeben, die die Signatur Ihres Stellvertreters verletzt.

Ihre Stellvertretung ändern zu

delegate TOut SomeDelegate<TIn, TOut>(Tin param); 

oder den eingebauten in Func delegates verwenden.

1

Sie werden wahrscheinlich ein Paar Delegierte benötigen. Das Problem hier ist, dass wir zwei Anwendungsfällen haben Sie verwenden wollen:

delegate T SomeDelegate<T>(T param); 

Oben ist ein einfacher Delegierter, was bedeutet, dass Sie übergeben in einem T, kein Lambda, die ein T zurückgibt. In diesem Fall würden Sie es so nennen: new SomeDelegate<string>(course.Name)

delegate T SomeDelegate<T>(Func<T> param); 

über eine etwas komplexere delegieren, das bedeutet, dass Sie in einer Funktion unterwegs sind, die zu T auswertet, wenn es fertig ist. Lambdas sind ziemlich gut im Umgang damit. In diesem Fall, dass Sie es so nennen würden: new SomeDelegate<string>(course => course.Name)

Sie können mehr über Lambda-Ausdrücke, Ausdrücke lesen, usw. hier: https://msdn.microsoft.com/en-us/library/bb397687.aspx