有没有办法从类型参数创建泛型类.
我有这样的事情:
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>();
}
}
Run Code Online (Sandbox Code Playgroud)
我想要的是从Type创建GenericClass.例如:
var SC = new SomeClass();
SC.TypeOfAnotherClass = typeof(OneMoreClass);
var generic = GenericClass.GetInstance(SC.TypeOfAnotherClass);
Assert.AreEqual(typeof(GenericClass<OneMoreClass>), generic.GetType());
Run Code Online (Sandbox Code Playgroud)
在这里,我希望获得实例,GenericClass<OneMoreClass>但我得到了GenericClass<Type>
我也尝试过使用那种类型的实例.例如:
var generic = GenericClass.GetInstance(Activator.CreateInstance(SC.TypeOfAnotherClass));
Run Code Online (Sandbox Code Playgroud)
这次我得到了 GenericClass<object>
有没有办法完成这项任务?
Cod*_*ike 10
如果你OneMoreClass在构建时知道你真正想要的类型(),那么你应该只使用它:
var generic = GenericClass.GetInstance<OneMoreClass>();
Run Code Online (Sandbox Code Playgroud)
但我假设你在构建时不知道它,并且必须type在运行时获得它.你可以用反射做,但它不漂亮,而且很慢:
public class GenericClass
{
public static object GetInstance(Type type)
{
var genericType = typeof(GenericClass<>).MakeGenericType(type);
return Activator.CreateInstance(genericType);
}
}
Run Code Online (Sandbox Code Playgroud)
由于您在构建时不知道结果类型,因此除了object(或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.");
}
Run Code Online (Sandbox Code Playgroud)
结果:
With Reflection: 243ms.
Without Reflection: 2ms.
Run Code Online (Sandbox Code Playgroud)
所以慢了100多倍.
关于泛型的真实要点是泛型中的<T>s在构建时由C#编译器解析,并插入实际的类名.当您必须将其推迟到运行时间时,您最终会支付性能价格.
| 归档时间: |
|
| 查看次数: |
3770 次 |
| 最近记录: |