2010-04-26 47 views
8

Tengo problemas para crear una colección de delegados utilizando reflexión y genéricos.Delegate.CreateDelegate() y genéricos: Error al vincular al método de destino

Estoy tratando de crear una colección de delegados de métodos Ally, que comparten una firma de método común.

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

Y los genéricos de cocina:

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

Pero el Delegate.CreateDelegate(delegateType, method) lanza una excepción ArgumentException diciendo error unirse a secuencias diana método. :/

¿Qué estoy haciendo mal?

Respuesta

16

Esto se debe a que la sobrecarga de Delegate.CreateDelegate solo admite la creación de delegados que apunten a métodos estáticos. Si desea vincularse a métodos de instancia, también debe pasar la instancia en la que se supone que el delegado creado llama al método.

es probable que desee:

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

Además, su ejemplo de código no se compilará. No puede declarar la variación en las firmas de métodos; y no puede omitir la implementación en una clase no abstracta.

Finalmente, Delegate.CreateDelegate crea un delegado instancia, que no puede existir sin conocer sus parámetros de tipo. Por lo tanto, no puede vincularse a classyDelegate <,>, necesita conocer los tipos reales involucrados.

+0

Hola Driis! Gracias por su respuesta. ¿Qué quiere decir con 'No puede declarar varianza en las firmas de métodos'? – SDReyes

+3

Se refiere a las palabras clave 'out' y' in' en sus argumentos genéricos. – gix

+1

Quiero decir que no puedes tener los modificadores de entrada y salida en las firmas de tu método en la clase. Solo puede tenerlos en las declaraciones de delegado y de interfaz. – driis

Cuestiones relacionadas