2012-01-13 3 views
1

런타임에만 알 수있는 속성 형식을 가져와 일반 메서드의 형식 매개 변수로 전달해야합니다. 예를 들어 :일반 메서드로 전달할 속성 형식 가져 오기

PropertyInfo prop = Bar.GetProperty("Property1"); 

//"type 'prop' could not be found" error 
Foo<prop.PropertyType>(); 

void Foo<T>() 
{ 
    //Stuff 
} 
class Bar 
{ 
    string Property1{get;set;} 
} 

Bar.Property1의 유형이 컴파일시에 알려지지 않을 것이다, 그래서 나는 Foo<string>(); 할 수 없습니다. Foo<dynamic>();을 사용하면 올바르게 컴파일되고 실행되지만 그 방법이 가장 좋은 방법이라고 확신하지는 않습니다. 이전 프레임 워크를 사용하여이를 수행 할 방법이 있는지 알고 싶습니다.


희망은,이보다 완전한 예를 들어 내 의도를 명확하게됩니다

public void Map(TInType inObject, TOutType outObject) 
    { 
     //propertyIn, propertyOut, and converter are all strings identifying the properties/methods to be used from the inObject/Type outObject/Type. 
     SetPropertyValues<dynamic, dynamic>(inObject, outObject, propertyIn, propertyOut, converter); 
    } 
    private void SetPropertyValues<TPropIn,TPropOut>(TInType fromObject, TOutType toObject, string propertyIn, string propertyOut, string converter) 
    { 
     PropertyInfo prop1 = typeof(TInType).GetProperty(propertyIn); 
     MethodInfo converterMethod = typeof(TInType).GetMethod(converter); 
     PropertyInfo prop2 = typeof(TOutType).GetProperty(propertyOut); 

     prop2.SetValue(
      toObject, 
      CopyPropertyValue<TPropIn, TPropOut>((TPropIn)prop1.GetValue(fromObject, null), p => (TPropOut)converterMethod.Invoke(fromObject, new object[] { p })), 
      null); 
    } 
    private TPropOut CopyPropertyValue<TPropIn, TPropOut>(TPropIn InPropValue, Func<TPropIn, TPropOut> converterFunction) 
    { 
     return converterFunction(InPropValue); 
    } 

나는 사람이 가질 수있는 다른 제안에 열려있어, 또는 코드가 뒤로 샷 밖으로 이동해야, 하지만 내 원래의 질문은 여전히 ​​내가 가장 관심이있는 것입니다.

+0

리플렉션을 통해 메소드를 호출 할 수 있지만 이것이 올바른 해결책인지는 분명하지 않습니다. –

+1

이 질문보기 : http://stackoverflow.com/questions/266115/pass-an-instantiated-system-type-as-a-type-parameter-for-a-generic-class – Ray

+0

'Foo' 일단 그것이 그것이 무엇인지 안다면 'T'형과 관련이 있는가? 'Foo'의 실제 구현은'void Foo (T val)'과 더 비슷합니까? –

답변

1

MakeGenericMethod를 사용할 수 있습니다. 성능은 실제로 상당히 합리적이며 무엇을 호출할지 명시 적으로 정의 할 수 있으므로 오버 헤드가 줄어 듭니다. 다음과 같이 Invoker는 필요한 명시적인 메서드/클래스를 호출하고 도우미는 실제로 제네릭 호출을 호출합니다.

public class GenericHelper 
{ 
    public static void DoSomethingGeneric(GenericInvokerParameters parameters) 
    { 
     var targetMethodInfo = typeof(GenericInvoker).GetMethod("DoSomethingGeneric"); 
     var genericTargetCall = targetMethodInfo.MakeGenericMethod(parameters.InvokeType); 
     genericTargetCall.Invoke(new GenericInvoker(), new[] { parameters }); 
    } 
} 

public class GenericInvoker 
{ 
    public void DoSomethingGeneric<T>(GenericInvokerParameters parameters) 
    { 
     //Call your generic class/method e.g. 
     SomeClass.SomeGenericMethod<T>(parameters.SomeValue); 
    } 
} 

public class GenericInvokerParameters 
{ 
    public GenericInvokerParameters(Type typeToInvoke, string someValue) 
    { 
     SomeValue = someValue; 
     InvokeType = typeToInvoke; 
    } 

    public string SomeValue { get; private set; } 
    public Type InvokeType { get; private set; } 
} 
1

dynamic에 아무것도 표시되지 않습니다. 사용하십시오.

편집이 당신이 반사 성능의 관점에서 비트는, 내가 선호 수있는 고주파와 그 메소드를 호출하지 않을거야까지

dynamic

0

푸 제네릭 안 당신이 그것을 일반적으로 사용하지 않는다면.

관련 문제