Указание универсального для возврата объекта динамического типа - PullRequest
0 голосов
/ 30 марта 2010

Этот вопрос является своего рода продолжением моего первоначального вопроса здесь .

Допустим, у меня есть следующий родовой класс (упрощение! ^ _ ^):

class CasterClass<T> where T : class
{
    public CasterClass() { /* none */ }
    public T Cast(object obj)
    {
        return (obj as T);
    }
}

Который обладает способностью приводить объект в указанный тип.

К сожалению, во время компиляции я не могу себе позволить точно знать, с какими типами мне придется работать, поэтому мне придется создать экземпляр этого класса с помощью отражения, например:

Type t = typeof(castedObject);

// creating the reflected Caster object
object CasterObj = Activator.CreateInstance(
    typeof(CasterClass<>).MakeGenericType(t)
);

// creating a reflection of the CasterClass' Cast method
MethodInfo mi = typeof(CasterClass<>).GetMethod("Cast");

Проблема в том, что когда я вызываю метод с помощью mi.Invoke (), он возвращает вывод с типизированным объектом вместо специально типизированного экземпляра T (из-за отражения).

Есть ли способ заставить метод, вызываемый через отражение, возвращать динамический тип, как показано выше? Я почти уверен, что в .NET 3.5 нет средств для приведения в динамический тип (точнее, это было бы очень непрактично).

Большое спасибо!

Ответы [ 2 ]

0 голосов
/ 20 декабря 2011

Просто передайте любой тип в ObjectCreateMethod, и вы получите обработчик динамического метода, который позже вы сможете использовать для приведения универсального объекта в определенный тип, вызывая CreateInstance.

ObjectCreateMethod _MyDynamicMethod = new ObjectCreateMethod(info.PropertyType);
object _MyNewEntity = _MyDynamicMethod.CreateInstance();

Назовите этот класс:

using System.Reflection;
using System.Reflection.Emit;

public class ObjectCreateMethod
{
    delegate object MethodInvoker();
    MethodInvoker methodHandler = null;

    public ObjectCreateMethod(Type type)
    {
        CreateMethod(type.GetConstructor(Type.EmptyTypes));
    }

    public ObjectCreateMethod(ConstructorInfo target)
    {
        CreateMethod(target);
    }

    void CreateMethod(ConstructorInfo target)
    {
        DynamicMethod dynamic = new DynamicMethod(string.Empty,typeof(object),new Type[0], target.DeclaringType);
        ILGenerator il = dynamic.GetILGenerator();
        il.DeclareLocal(target.DeclaringType);
        il.Emit(OpCodes.Newobj, target);
        il.Emit(OpCodes.Stloc_0);
        il.Emit(OpCodes.Ldloc_0);
        il.Emit(OpCodes.Ret);

        methodHandler = (MethodInvoker)dynamic.CreateDelegate(typeof(MethodInvoker));
    }

    public object CreateInstance()
    {
        return methodHandler();
    }
}
0 голосов
/ 30 марта 2010

Если у вас есть контроль над классами, с которыми вы будете работать, пусть все они создадут интерфейс, содержащий методы, которые вы будете вызывать, и после создания приведите к интерфейсу.

Я также опубликовал ответ на ваш предыдущий вопрос с той же идеей.

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