您可以看到我正在尝试(但失败)使用以下代码执行的操作:
protected T GetObject()
{
return new T();
}
任何帮助将不胜感激。
编辑:
上下文如下。我正在使用标准化方法为所有控制器派生一个自定义控制器类。因此,在上下文中,我需要创建控制器类型对象的新实例。所以在写这篇文章的时候,它是这样的:
public class GenericController<T> : Controller
{
...
protected T GetObject()
{
return (T)Activator.CreateInstance(ObjectType);
}
public ActionResult Create()
{
var obj = GetObject()
return View(obj);
}
所以我决定在这里反思是最容易的。我同意,当然考虑到问题的初始陈述,标记为正确的最合适答案是使用 new() 约束的答案。我已经解决了。
public class MyClass<T> where T : new()
{
protected T GetObject()
{
return new T();
}
}
T
可能是没有默认构造函数的类:在这种情况下 new T()
将是无效语句。 new()
约束表明 T
必须具有默认构造函数,这使得 new T()
合法。
您可以将相同的约束应用于泛型方法:
public static T GetObject<T>() where T : new()
{
return new T();
}
如果需要传递参数:
protected T GetObject(params object[] args)
{
return (T)Activator.CreateInstance(typeof(T), args);
}
为什么没有人建议 Activator.CreateInstance
?
http://msdn.microsoft.com/en-us/library/wccyzw83.aspx
T obj = (T)Activator.CreateInstance(typeof(T));
另一种方法是使用反射:
protected T GetObject<T>(Type[] signature, object[] args)
{
return (T)typeof(T).GetConstructor(signature).Invoke(args);
}
new constraint 很好,但如果您也需要 T 作为值类型,请使用:
protected T GetObject() {
if (typeof(T).IsValueType || typeof(T) == typeof(string)) {
return default(T);
} else {
return (T)Activator.CreateInstance(typeof(T));
}
}
只是为了完成,这里最好的解决方案通常是需要一个工厂函数参数:
T GetObject<T>(Func<T> factory)
{ return factory(); }
并称其为:
string s = GetObject(() => "result");
如果需要,您可以使用它来要求或使用可用参数。
由于这被标记为 C# 4。使用开源框架 ImpromptuIntereface,它将使用 dlr 调用构造函数,当你的构造函数有参数时,它比 Activator 快得多,而当它没有参数时,速度可以忽略不计。然而,主要优点是它可以正确处理带有 C# 4.0 可选参数的构造函数,而 Activator 不会这样做。
protected T GetObject(params object[] args)
{
return (T)Impromptu.InvokeConstructor(typeof(T), args);
}
为此,我尝试了以下代码:
protected T GetObject<T>()
{
T obj = default(T);
obj =Activator.CreateInstance<T>();
return obj ;
}