从类型参数泛型类 [英] Generic class from type parameter

查看:194
本文介绍了从类型参数泛型类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有没有一种方法来创建类型参数泛型类

Is there a way to create a generic class from type parameter.

我有这样的事情:

public class SomeClass
{
    public Type TypeOfAnotherClass { get; set; }
}

public class OneMoreClass
{
}

public class GenericClass<T>
    where T : class
{
    public void DoNothing() {}
}

public class GenericClass
{
    public static GenericClass<T> GetInstance<T>(T ignored)
        where T : class
    {
        return new GenericClass<T>();
    }
}



我要的是从一个类型创建一个GenericClass 。例如:

What I want is to create a GenericClass from a Type. Ex:

var SC = new SomeClass();
SC.TypeOfAnotherClass = typeof(OneMoreClass);
var generic = GenericClass.GetInstance(SC.TypeOfAnotherClass);

Assert.AreEqual(typeof(GenericClass<OneMoreClass>), generic.GetType());



在这里,我希望得到 GenericClass<的实例; OneMoreClass> ,但我得到 GenericClass<类型>

我使用该类型的实例,也试过。例如:

I also tried using instance of that type. Ex:

var generic = GenericClass.GetInstance(Activator.CreateInstance(SC.TypeOfAnotherClass));

这一次我 GenericClass<对象>

有没有办法来完成这项任务?

Is there a way to accomplish this task?

推荐答案

如果你知道在编译的时候,你真正想要的类型( OneMoreClass ),那么你应该只使用它:

If you know the type you actually want (OneMoreClass) at build time, then you should just use it:

var generic = GenericClass.GetInstance<OneMoreClass>();



但我假设你不知道它在制作的时候,并获得键入在运行时。
你可以用反射做到这一点,但它不是漂亮,是缓慢的:

But I am assuming you don't know it at build time, and have to get the type at runtime. You can do it with reflection, but it isn't pretty, and is slow:

public class GenericClass
{
    public static object GetInstance(Type type)
    {
        var genericType = typeof(GenericClass<>).MakeGenericType(type);
        return Activator.CreateInstance(genericType);
    }
}



因为你不知道在构建结果类型时候,你可以不返回任何东西,但对象(或动态)的方法。

下面是慢多少(100,000创建)

Here is how much slower (for 100,000 creates)

public class GenericClass
{
    public static object GetInstance(Type type)
    {
        var genericType = typeof(GenericClass<>).MakeGenericType(type);
        return Activator.CreateInstance(genericType);
    }

    public static GenericClass<T> GetInstance<T>()
        where T : class
    {
        return new GenericClass<T>();
    }
}

    [Test]
    public void CanMakeGenericViaReflection_ButItsSlow()
    {
        var timer = new Stopwatch();
        var SC = new SomeClass();
        SC.TypeOfAnotherClass = typeof(OneMoreClass);

        timer.Start();
        for (int x = 0; x < 100000; x++)
        {
            GenericClass.GetInstance(SC.TypeOfAnotherClass);
        }
        timer.Stop();
        Console.WriteLine("With Reflection: " + timer.ElapsedMilliseconds + "ms.");

        timer.Restart();
        for (int x = 0; x < 100000; x++)
        {
            GenericClass.GetInstance<OneMoreClass>();
        }
        timer.Stop();
        Console.WriteLine("Without Reflection: " + timer.ElapsedMilliseconds + "ms.");
    }



结果:

Results:

With Reflection: 243ms.
Without Reflection: 2ms.



所以稍微超过100倍的速度较慢。

So a little over 100x slower.

要注意的泛型真实的东西是,< T> S IN仿制药在被解析的由C#编译器编译时的,并真正的类名被插入。当你有推迟直到运行时,你为此付出的性能价格比。

The real thing to note about generics is that the <T>s in generics are resolved at build-time by the C# compiler, and the real class names are inserted. When you have to defer that until run-time, you end up paying the performance price.

这篇关于从类型参数泛型类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆