public class GenericTests { public T CompileError<T>() // compile error CS0304 { return new T(); } public T CreateWithNew<T>() where T : new() // builds ok { return new T(); } public T CreateWithActivator<T>() // builds ok { return Activator.CreateInstance<T>(); } }
为什么是这样?
根据https://stackoverflow.com/a/1649108/531971,其引用MSDN documentation和this question,泛型中的新的T()表达式实际上是使用Activator.CreateInstance< T>()实现的.所以我不明白为什么调用新的T()需要通用类型被限制在使用Activator.CreateInstance< T>()时可以省略的方式.
或者,以相反的方式提出问题:T:new()约束在何处可以通过直接使用完全相同的基础架构轻松地创建一个没有约束的通用方法中的T的实例?
解决方法
> Activator.CreateInstance< T> – 我想使用它的默认构造函数创建一个新的T实例 – 如果没有一个异常(由于发生了一些非常错误的事情,我想要处理它/自己抛出).
附注:请注意as MSDN says:
In general,there is no use for the
CreateInstance<T>()
generic method in application code,because the type must be known at compile time. If the type is known at compile time,normal instantiation Syntax can be used.
因为一般来说,当编译时已知类型(CreateInstance< T>(07-07))时,您将希望使用一个构造函数,这是较慢的[也就是Activator.CreateInstance< T>本身不需要约束]).
> T() – 我想调用T的空构造函数,据称是一个标准的构造函数调用.
您不希望“标准”构造函数调用失败,因为“没有这样的构造函数被发现”,因此,编译器希望你约束有一个.
比那更多的;您应该优先考虑编译时间错误超过例外情况.
事实上,T()在内部使用与“我只想要一个默认实例T”的平均情况无关的反射(当然,如果你关心性能等等,内部实现很重要).