Получить тип свойства для передачи в универсальный метод - PullRequest
1 голос
/ 13 января 2012

Мне нужно получить тип свойства, которое будет известно только во время выполнения, и передать его в качестве параметра типа для универсального метода. Например:

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

Я открыт для любых других предложений, которые могут быть у кого-либо, или для того, чтобы код был взят обратно и снят, но мой первоначальный вопрос по-прежнему наиболее интересен.

Ответы [ 3 ]

2 голосов
/ 13 января 2012

Вы можете использовать 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 голос
/ 13 января 2012

Не вижу ничего плохого в dynamic.Используйте его.

EDIT

Пока вы не собираетесь вызывать этот метод с высокой частотой, где отражение может отразить его от производительностив перспективе я бы предпочел dynamic

0 голосов
/ 13 января 2012

Foo не должен быть универсальным, если вы не используете его в общем. Просто заставьте его работать с типом Object вместо T.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...