有没有办法从类型参数创建泛型类。
我有这样的事情:
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>();
}
}
我想要的是从类型创建一个通用类。前任:
var SC = new SomeClass();
SC.TypeOfAnotherClass = typeof(OneMoreClass);
var generic = GenericClass.GetInstance(SC.TypeOfAnotherClass);
Assert.AreEqual(typeof(GenericClass<OneMoreClass>), generic.GetType());
在这里我希望得到的实例GenericClass<OneMoreClass>
但我得到GenericClass<Type>
我也尝试过使用该类型的实例。前任:
var generic = GenericClass.GetInstance(Activator.CreateInstance(SC.TypeOfAnotherClass));
这次我得到GenericClass<object>
有办法完成这个任务吗?
如果您知道您真正想要的类型(OneMoreClass
)在构建时,那么你应该使用它:
var generic = GenericClass.GetInstance<OneMoreClass>();
但我假设你在构建时不知道它,并且必须获得type
在运行时。
你可以通过反射来做到这一点,但它不漂亮,而且很慢:
public class GenericClass
{
public static object GetInstance(Type type)
{
var genericType = typeof(GenericClass<>).MakeGenericType(type);
return Activator.CreateInstance(genericType);
}
}
由于您在构建时不知道结果类型,因此您不能返回任何内容,但object
(or dynamic
)从方法。
这是慢了多少(对于 100,000 个创建)
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 倍多一点。
关于泛型真正需要注意的是<T>
泛型中的 s 被解析为构建时由 C# 编译器执行,并插入真实的类名。当您必须将其推迟到运行时时,您最终会付出性能代价。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)