2012-06-21 2 views
4

나는 바퀴가 어떻게 돌아가는지를 이해할 수 있도록 부분적으로 바퀴를 새롭게 만들었다.유형이 Type으로 컴파일 된 생성자 표현하기

유형의 기본 생성자를 컴파일하고 반환하기 위해이 일반 함수를 고려하십시오.

public static Func<TConcrete> Creator<TConcrete>() 
{ 
    // All checking removed for brevity 
    var ctor = typeof(TConcrete).GetConstructor(new Type[0]); 
    var lambda = Expression.Lambda<Func<TConcrete>>(Expression.New(ctor)); 
    return lambda.Compile(); 
} 

저는 이것이 전달 된 유형을 인스턴스화하는 데 사용할 수있는 훌륭한 형식화 된 대리자를 반환한다고 생각합니다.

다른 유형의 집합에 대해이 작업을 수행하는 기능을 원한다면 어떻게할까요? 난 당신이 ????에서 볼 수 있듯이 내가 붙어있어 어디

public static IEnumerable<Delegate> Creators(IEnumerable<Type> types) 
{ 
    foreach (var type in types) 
    { 
     var ctor = type.GetConstructor(new Type[0]); 
     var lamda = Expression.Lambda<Func<????>>(Expression.New(ctor)); 
     yield return lambda.Compile(); 
    } 
} 

이는 ...의 라인을 따라 thiking했다. 이 방법이 있습니까 아니면 내 접근법에 결함이 있습니까?

+0

'Creators' 메서드를 호출하고 반환 된 델리게이트를 사용하는 코드는 어떻게 생겼습니까? – dtb

+0

@dtb, 그 코드는 실제로 존재하지 않는다. 내 프로그램은 실제로 인터페이스와 구체적인 구현 간의 연관성을 전달하기 위해 IEnumerable >을 사용하는 함수를 가지고 있지만, 나는 실제 질문에 불필요하다고 생각했다. – Jodrell

답변

5

사용 MakeGenericType와 함께 비 일반 과부하 :

var lamda = Expression.Lambda<Func<????>>(Expression.New(ctor)); 

이 될해야 :

var funcType = typeof(Func<>).MakeGenericType(type); 
var lamda = Expression.Lambda(funcType, Expression.New(ctor)); 
+0

젠장, 그건 분명했다, 감사합니다 – Jodrell

6

당신은 Type으로 대리자 형식을 취 다른 Expression.Lambda 호출 사용할 수 있습니다

Type delegateType = typeof(Func<>).MakeGenericType(type); 
var lambda = Expression.Lambda(delegateType, Expression.New(ctor)); 
yield return lambda.Compile(); 

Lambda의로드는 Expression<TDelegate>이 아닌 LambdaExpression 비 일반 형식을 반환하지만 Delegate을 반환하는 Compile 메서드를 여전히 제공합니다. 여기에 모두 필요합니다. 기본적으로 "알려진 델리게이트 유형"코드의 이점을 활용할 수있는 컴파일 타임 유형 검사를 피하는 것입니다.

+0

사실, 고마워. 내 인텔리 센스를 읽을 시간을 좀 보냈어야 했어. – Jodrell

관련 문제