2010-04-26 15 views
8

Si verificano problemi durante la creazione di una raccolta di delegate mediante reflection e generics.Delegate.CreateDelegate() e generics: Errore durante il binding al metodo target

Sto provando a creare una raccolta delegata dai metodi di Ally, la cui condivisione è una firma di metodo comune.

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... 
} 

E i farmaci generici cottura:

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

Ma la Delegate.CreateDelegate(delegateType, method) getta un ArgumentException dicendo errore legame al metodo di destinazione. :/

Cosa sto facendo male?

risposta

16

Questo perché il sovraccarico di Delegate.CreateDelegate supporta solo la creazione di delegati che puntano a metodi statici. Se si desidera associare a metodi di istanza, è inoltre necessario passare l'istanza in cui il delegato creato deve chiamare il metodo.

probabilmente si vuole:

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

Inoltre, il tuo esempio di codice non viene compilato. Non è possibile dichiarare la varianza sulle firme dei metodi; e non puoi omettere l'implementazione in una classe non astratta.

Infine, Delegate.CreateDelegate crea un Delegato istanza, che non può esistere senza conoscere i parametri di tipo. Pertanto, non è possibile associare a classyDelegate <,>, è necessario conoscere i tipi effettivi coinvolti.

+0

Ciao Driis! Grazie per la vostra risposta. Cosa intendi con 'Non puoi dichiarare la varianza sulle firme dei metodi'? – SDReyes

+3

Intende le parole chiave 'out' e' in' sugli argomenti generici. – gix

+1

Voglio dire che non puoi avere il fuori e in modificatori sulle firme dei metodi nella classe. Puoi averli solo su delegati e dichiarazioni dell'interfaccia. – driis