我读了一篇关于泛型类的培训文章,它有一些像这样的代码:
public class ValidationBase {
public virtual bool IsValidName(string name) {
return name.Length > 5;
}
}
public class LogicBase<T> where T : ValidationBase, new() {
private T _Validations = default(T);
public T Validations {
get {
if (_Validations == null) {
_Validations = new T();
}
return _Validations;
}
set { _Validations = value; }
}
}
它说:
如果没有为T提供特定类型,则new关键字默认创建DataModelBase类的实例
我真的不明白何时应该使用new()
关键字?
注意:如果编辑上面这样的代码:
public class LogicBase<T> where T : ValidationBase
而不是
public class LogicBase<T> where T : ValidationBase, new()
将会发生什么?
答案 0 :(得分:4)
指定泛型类时,new()
充当T
可以类型的约束。
在这种情况下,new()
表明T
的类型必须是具有公共无参数构造函数的类。
例如:
public class MyGenericClass<T> where T : new()
{
}
public class MyClass
{
public MyClass()
{
}
}
public class MyClass2
{
public MyClass2(int i)
{
}
}
class Program
{
static void Main(string[] args)
{
// OK!
MyGenericClass<MyClass> c1 = new MyGenericClass<MyClass>();
// Gives the error:
// 'MyClass2' must be a non-abstract type with a public parameterless
// constructor in order to use it as parameter 'T' in the generic type
// or method 'MyGenericClass<T>'
MyGenericClass<MyClass2> c2 = new MyGenericClass<MyClass2>();
}
}
这样您就可以使用T
创建new T()
类型的新实例。由于这是通用的,所有类型的T
必须符合相同的规则。 where T: new()
强制所有类型的T
都有一个公共的无参数构造函数。
你编码:
if (_Validations == null) {
_Validations = new T();
}
创建T
的新实例。由于T
可以是任何内容,因此必须能够使用T
创建所有类型的new MyType()
。
答案 1 :(得分:2)
New T()
用于使用没有参数的构造函数创建T的新实例。只有在通用定义中使用new()
约束时才可以这样做。
答案 2 :(得分:2)
LogicBase的定义指出T将是ValidationBase类型,而LogicBase将创建ValidationBase类型的新实例。 new()是一个约束。
基本上你要设置一个约束,说ValidationBase类型应该有一个公共无参数构造函数。
这是一个重要的例子,让我们说ValidationBase是一个抽象类,你把它作为类型参数传递给LogicBase,在这种情况下,LogicBase会给出一个编译错误,因为你不能创建抽象类的实例。
答案 3 :(得分:1)
在以下代码段中,您试图获取任意类T
的实例:
if (_Validations == null) {
_Validations = new T();
}
但由于T
是一个泛型类型参数,并且可以是任何内容,因此实际上无法保证T
的实例可以像这样新建。为了编译它,您必须向编译器保证您为LogicBase<T>
提供的任何类型参数确实具有不带参数的构造函数。
您可以在类定义中使用new
类型约束来保证这一点。这将确保您在任何地方T
,(例如,在实例化或从LogicBase<FooBar>
派生时),为T
提供的类型参数(在前面的示例中,FooBar
)有一个空构造函数。如果没有匹配的构造函数可用,则会出现编译器错误。