从类型参数泛型类 [英] Generic class from type parameter
问题描述
有没有一种方法来创建类型参数泛型类
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屋!