【问题标题】:Instructing a generic to return an object of a dynamic type指示泛型返回动态类型的对象
【发布时间】:2011-02-02 12:00:24
【问题描述】:

这个问题是我最初的问题here 的后续问题。

假设我有以下泛型类(简化!^_^):

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 不具备转换为动态类型的功能(或者说,这是非常不切实际的)。

非常感谢!

【问题讨论】:

    标签: c# generics reflection .net-3.5


    【解决方案1】:

    如果您可以控制要使用的类,请让它们都实例化一个包含您将要调用的方法的接口,并在实例化后强制转换为接口。

    我也用同样的想法发布了你之前问题的答案。

    【讨论】:

    • 谢谢马克,可能就是这样。不过,我将不得不对此进行更多研究,但这很有意义。
    【解决方案2】:

    只需将任何类型传递给 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();
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-08-04
      • 1970-01-01
      • 2011-05-07
      • 1970-01-01
      • 1970-01-01
      • 2021-06-02
      • 2023-03-06
      • 1970-01-01
      相关资源
      最近更新 更多