获取要传递给泛型方法的属性类型

本文关键字:属性 类型 泛型方法 获取 | 更新日期: 2023-09-27 18:20:18

我需要获得一个只有在运行时才知道的属性的类型,并将其作为泛型方法的类型参数传递。例如:

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);
    }

我愿意接受任何人可能提出的任何其他建议,或者应该把代码拿回来拍摄,但我最初的问题仍然是我最感兴趣的问题。

获取要传递给泛型方法的属性类型

您可以使用MakeGenericMethod,性能实际上是相当合理的,并且允许您显式定义您用什么调用什么,从而减少了开销。因此,类似于下面的内容,Invoker将调用您需要的显式方法/类,而helper实际上调用了泛型调用。

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

不要在dynamic中看到任何不好的东西。使用它。

编辑

除非你不打算用高频率调用该方法,从性能的角度来看,反射可能会比特,否则我更喜欢dynamic

Foo如果不是通用的,就不应该是通用的。只需使其在类型Object而不是T.上操作即可