C#创build新的T()
你可以看到我正在尝试(但失败)做以下代码:
protected T GetObject() { return new T(); }
任何帮助将不胜感激。
编辑:
背景如下。 我正在玩所有控制器的自定义控制器类,以标准化方法派生。 所以在上下文中,我需要创build一个控制器types的对象的新实例。 所以在写作的时候,是这样的:
public class GenericController<T> : Controller { ... protected T GetObject() { return (T)Activator.CreateInstance(ObjectType); } public ActionResult Create() { var obj = GetObject() return View(obj); }
所以我决定在这里最简单的reflection。 我同意,当然在给出问题的最初陈述之后,标记为正确的最恰当的答案是使用new()约束的答案。 我已经解决了。
看看新的约束
public class MyClass<T> where T : new() { protected T GetObject() { return new T(); } }
T
可能是一个没有默认构造函数的类:在这种情况下, new T()
将是一个无效的语句。 new()
约束表示T
必须有一个默认的构造函数,这使得new T()
合法。
您可以将相同的约束应用于generics方法:
public static T GetObject<T>() where T : new() { return new T(); }
如果你需要传递参数:
protected T GetObject(params object[] args) { return (T)Activator.CreateInstance(typeof(T), args); }
为什么没有人build议Activator.CreateInstance
?
http://msdn.microsoft.com/en-us/library/wccyzw83.aspx
T obj = Activator.CreateInstance(typeof(T));
另一种方法是使用reflection:
protected T GetObject<T>(Type[] signature, object[] args) { return (T)typeof(T).GetConstructor(signature).Invoke(args); }
为了完成,这里最好的解决scheme通常需要一个工厂函数参数:
T GetObject<T>(Func<T> factory) { return factory(); }
并称之为这样的事情:
string s = GetObject(() => "result");
如果需要,您可以使用它来要求或使用可用的参数。
新的约束是好的,但如果你需要T也是一个值types,使用这个:
protected T GetObject() { if (typeof(T).IsValueType || typeof(T) == typeof(string)) { return default(T); } else { return (T)Activator.CreateInstance(typeof(T)); } }
因为这是C#4的标签。使用开放的sourece框架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 ; }