2012-01-13 48 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即可。