2010-04-26 3 views
8

Ich habe Probleme beim Erstellen einer Sammlung von Delegaten mit Reflektion und Generics.Delegate.CreateDelegate() und Generics: Fehler beim Binden an die Zielmethode

Ich versuche, eine Delegat-Sammlung von Ally-Methoden zu erstellen, die eine gemeinsame Methodensignatur teilen.

public class Classy 
{ 
    public string FirstMethod<T1, T2>(string id, Func<T1, int, IEnumerable<T2>> del); 
    public string SecondMethod<T1, T2>(string id, Func<T1, int, IEnumerable<T2>> del);  
    public string ThirdMethod<T1, T2>(string id, Func<T1, int, IEnumerable<T2>> del); 

    // And so on... 
} 

Und der Koch Generika:

// This is the Classy's shared method signature  
public delegate string classyDelegate<out T1, in T2>(string id, Func<T1, int, IEnumerable<T2>> filter); 


// And the linq-way to get the collection of delegates from Classy 
( 
    from method in typeof(Classy).GetMethods(BindingFlags.Instance | BindingFlags.DeclaredOnly | BindingFlags.NonPublic) 
    let delegateType = typeof(classyDelegate<,>) 
    select Delegate.CreateDelegate(delegateType, method) 
).ToList(); 

Aber die Delegate.CreateDelegate(delegateType, method) wirft ein Argument sagen Error-Methode zum Ziel zu binden. :/

Was mache ich falsch?

Antwort

16

Das liegt daran, dass die Überladung von Delegate.CreateDelegate nur das Erstellen von Delegaten unterstützt, die auf statische Methoden verweisen. Wenn Sie an Instanzmethoden binden möchten, müssen Sie auch die Instanz übergeben, auf der der erstellte Delegat die Methode aufrufen soll.

Sie wollen wahrscheinlich:

from method in typeof(Classy).GetMethods(BindingFlags.Instance | BindingFlags.DeclaredOnly | BindingFlags.NonPublic) 
let delegateType = typeof(classyDelegate<,>) 
select Delegate.CreateDelegate(delegateType, yourInstance, method) 

Auch Ihr Codebeispiel wird nicht kompiliert. Sie können die Varianz für Methodensignaturen nicht deklarieren. und Sie können die Implementierung in einer nicht abstrakten Klasse nicht weglassen.

Schließlich erstellt Delegate.CreateDelegate einen Delegaten Instanz, die nicht existieren kann, ohne zu wissen, es ist Typparameter. Daher können Sie nicht binden an classyDelegate <,>, müssen Sie die tatsächlichen Typen beteiligt wissen.

+0

Hallo Driis! danke für Ihre Antwort. Was meinen Sie mit 'Sie können keine Varianz für Methodensignaturen deklarieren'? – SDReyes

+3

Er meint die Out- und In-Schlüsselwörter für Ihre generischen Argumente. – gix

+1

Ich meine, dass Sie nicht die Modifizierer out und in Ihrer Methode Signaturen in der Klasse haben können. Sie können sie nur auf Delegaten- und Interface-Deklarationen haben. – driis

Verwandte Themen