当前位置:  开发笔记 > 编程语言 > 正文

.NET Generics:使用Activator创建的类型作为泛型显示错误的Type?需要解决方法

如何解决《.NETGenerics:使用Activator创建的类型作为泛型显示错误的Type?需要解决方法》经验,为你挑选了1个好方法。

这真的让我今天难过.我确定它很简单,但是......这是我的示例代码:

using System;
using System.Collections;

namespace ConsoleApplication1
{
    class Program
    {
        public ArrayList SomeProp { get; set; }

        static void Main(string[] args)
        {
            // Get the Type of a property by reflection.
            Type myPropType = typeof(Program).GetProperty("SomeProp").PropertyType;

            // Create an instance of the determined Type.
            var x = Activator.CreateInstance(myPropType);

            // Now try to use that instance, passing to a method that takes a generic.
            WhatAmI(x);

            Console.ReadKey();
        }

        private static void WhatAmI(T x)
        {
            Console.WriteLine("T is: " + typeof(T).FullName);
            Console.WriteLine("x is: " + x.GetType().FullName);
        }
    }
}

这里的输出是:

T is: System.Object
x is: System.Collections.ArrayList

基本上这里发生的是我在某些课上有一些属性.它来自何处/何处并不重要.重要的是我得到了该属性的PropertyInfo.从那里我用Activator创建了一个新的Type实例.

现在,如果我将创建的实例传递给采用泛型参数的函数,则泛型类型总是作为Object出现,因为Activator.CreateInstance()返回一个Object,因此"var x"是一个Object,在这种情况下,不是一个ArrayList.

我需要发生的是泛型类型是实际类型,在他的情况下是"ArrayList".

我知道有一个我可以使用的Activator.CreateInstance(),但我不能在该方法的尖括号内使用Type(PropertyInfo.PropertyType).

我也可以只是转换返回的对象,如:

myPropType x = (myPropType)Activator.CreateInstance(myPropType);

但很明显,这不会编译...另外它无论如何都不会有效,因为演员是编译时间,我不知道直到运行时的类型,但从概念上讲它是我需要的......

所以我坚持使用这个Type,但我无法弄清楚如何将它传递给WhatAmI()方法,并且让T为ArrayList,而不是Object.

想法?



1> Marc Gravell..:

Type在运行时调用泛型方法,您需要使用反射 - MakeGenericMethod尤其是:

typeof(Program).GetMethod("WhatAmI",
    BindingFlags.Static | BindingFlags.NonPublic)
    .MakeGenericMethod(x.GetType()).Invoke(null, new object[] { x });

否则,编译器会从变量类型中推断出- object在这种情况下.

这里的一个侧面是你可以通过只进行一次反射来改进事物- 即不使用Activator,而是使用通用约束:

    private static void WhatAmI() where T : new()
    {
        T x = new T();
        Console.WriteLine("T is: " + typeof(T).FullName);
        Console.WriteLine("x is: " + x.GetType().FullName);
    }

定义没有 arg 的方法,但使用默认构造函数; 然后:

    // Get the Type of a property by reflection.
    Type myPropType = typeof(Program).GetProperty("SomeProp").PropertyType;

    // Now call a generic method just using the type
    typeof(Program).GetMethod("WhatAmI",
        BindingFlags.Static | BindingFlags.NonPublic)
            .MakeGenericMethod(myPropType).Invoke(null, null);

仅使用类型调用方法 - 在方法创建实例.这通常比重复反射更快.

推荐阅读
农大军乐团_697
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有