2010-04-26 2 views
8

리플렉션 및 제네릭을 사용하여 대리인 컬렉션을 만드는 데 문제가 있습니다.Delegate.CreateDelegate() 및 제네릭 : 대상 메서드에 대한 바인딩 오류

공통 메서드 시그니처를 공유하는 Ally 메서드에서 대리자 컬렉션을 만들려고합니다. 요리

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

그리고 제네릭 :

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

그러나 Delegate.CreateDelegate(delegateType, method) 오류가 방법을 대상으로 바인딩 말하는 ArgumentException이 발생합니다. :/

내가 뭘 잘못하고 있니?

답변

16

Delegate.CreateDelegate의 오버로드가 정적 메서드를 가리키는 대리자 만들기 만 지원하기 때문입니다. 인스턴스 메서드에 바인딩하려면 생성 된 대리자가 메서드를 호출하기로되어있는 인스턴스를 전달해야합니다.

당신은 아마 원하는 :

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

, 코드 예제는 컴파일되지 않습니다. 메서드 시그니처에 대한 분산은 선언 할 수 없습니다. 비 추상 클래스에서 구현을 생략 할 수는 없습니다.

마지막으로 Delegate.CreateDelegate는 인스턴스 인을 만듭니다.이 유형은 유형 매개 변수를 모른 채 존재할 수 없습니다. 따라서 classyDelegate <,>에 바인드 할 수 없으므로 관련된 실제 유형을 알아야합니다.

+0

안녕하세요 Driis! 당신의 응답을 주셔서 감사합니다. '메소드 시그니처에 대한 분산을 선언 할 수 없습니까?'라는 의미는 무엇입니까? – SDReyes

+3

그는 일반적인 인수에'out'과'in' 키워드를 의미합니다. – gix

+1

클래스의 메서드 시그니처에 out 및 in 한정자를 사용할 수 없다는 것을 의미합니다. 델리게이트 및 인터페이스 선언에만 사용할 수 있습니다. – driis

관련 문제