2012-01-13 50 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

您可以通過反射來調用該方法,但是從您的問題中可以看出,這是否是真正的解決方案。 – 2012-01-13 16:19:55

+1

看到這個問題:http://stackoverflow.com/questions/266115/pass-an-instantiated-system-type-as-a-type-parameter-for-a-generic-class – Ray 2012-01-13 16:25:55

+0

你期望什麼'Foo'一旦知道它是什麼,就與'T'類型做什麼?你真的實施'Foo'更像是'void Foo (T val)'? – 2012-01-13 16:33:59

回答

1

您可以使用MakeGenericMethod,性能實際上相當合理,並允許您明確定義您所調用的內容,從而減少開銷。 因此,如下所示,調用者將調用您需要的顯式方法/類,而幫助者實際上調用泛型調用。

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

富不應該是通用的如果你一般不使用它。只需讓它在Object類型上運行而不是T即可。