“哪里T:class,new()”是什么意思?


Answers:


329

那是对通用参数的约束T。它必须是class(引用类型),并且必须具有公共的无参数默认构造函数。

这意味着T不能是intfloatdoubleDateTime或任何其他struct(值类型)。

string只要具有默认或无参数构造函数,它就可以是或任何其他自定义引用类型。


5
只是为了澄清,如果你不具备该类条款作为其中T的一部分......,那么它是安全的使用整型,浮点,双等
AboutDev

1
@AboutDev正确,您不必在通用类型参数上施加约束。但是,如果要创建只希望对引用或值类型起作用的泛型,则应指定。没有约束,您可以期望引用类型(类)或值类型(结构(int,float,double ...))。
NerdFury

1
那T:[接口名称],new()在哪里呢?您是否还需要一个无参数的构造函数?
文斯·蒂诺

3
为了澄清Justin的评论,空的构造函数没有语句(例如默认构造函数),而无参数的构造函数可能包含语句(例如初始化列表)。
DharmaTurtle '16

@VinceTino:new()精确指定“必须有一个公共的无参数构造函数”
扁平化,

162

这些是通用类型约束。您的情况有两个:

where T : class

表示该类型T必须是引用类型(而不是值类型)。

where T : new()

表示类型T必须具有无参数构造函数。有了此约束T field = new T();,您将可以在代码中执行类似的操作,否则您将无法做到。

然后,您可以使用逗号将两者结合起来以得到:

where T : class, new()

第二点和第三点很好,只是为了增加信息,我认为在泛型类型中进行反射时第二点很有用。例如。T t =新的T(); t.GetType()。GetProperty(“ ID”)。SetValue(t,uniqueId,null);
杰里·梁

1
我相信说T:class,new()在哪里是多余的,因为new()已经暗示了类,因为结构不能具有默认构造函数。
DharmaTurtle '16

@DharmaTurtle,“结构不能包含显式的无参数构造函数”,并不意味着它们没有一个,而是说您无法定义一个。来源:msdn.microsoft.com/tr-tr/library/aa288208
v=vs.71).aspx

121

其中T:struct

type参数必须是值类型。可以指定除Nullable之外的任何值类型。有关更多信息,请参见使用可空类型(C#编程指南)。

其中T:类

type参数必须是引用类型,包括任何类,接口,委托或数组类型。(请参阅下面的注释。)

T:new() 类型参数必须具有公共的无参数构造函数。与其他约束一起使用时,必须最后指定new()约束。

T:[基类名称]

类型参数必须是指定的基类或从指定的基类派生。

T:[接口名称]

type参数必须是或实现指定的接口。可以指定多个接口约束。约束接口也可以是通用的。

其中T:U

为T提供的类型实参必须是为U提供的实参或从其派生。这称为裸类型约束。


23
这很有用,但链接到source
Skean 2015年

26

classnew对泛型类型参数的T 2个约束
他们分别确保:

class

type参数必须是引用类型。这也适用于任何类,接口,委托或数组类型。

new

类型参数必须具有公共的无参数构造函数。与其他约束一起使用时,必须最后指定new()约束。

它们的组合意味着类型T必须是引用类型(不能是值类型),并且必须具有无参数构造函数。

例:

struct MyStruct { } // structs are value types

class MyClass1 { } // no constructors defined, so the class implicitly has a parameterless one

class MyClass2 // parameterless constructor explicitly defined
{
    public MyClass2() { }
}

class MyClass3 // only non-parameterless constructor defined
{
    public MyClass3(object parameter) { }
}

class MyClass4 // both parameterless & non-parameterless constructors defined
{
    public MyClass4() { }
    public MyClass4(object parameter) { }
}

interface INewable<T>
    where T : new()
{
}

interface INewableReference<T>
    where T : class, new()
{
}

class Checks
{
    INewable<int> cn1; // ALLOWED: has parameterless ctor
    INewable<string> n2; // NOT ALLOWED: no parameterless ctor
    INewable<MyStruct> n3; // ALLOWED: has parameterless ctor
    INewable<MyClass1> n4; // ALLOWED: has parameterless ctor
    INewable<MyClass2> n5; // ALLOWED: has parameterless ctor
    INewable<MyClass3> n6; // NOT ALLOWED: no parameterless ctor
    INewable<MyClass4> n7; // ALLOWED: has parameterless ctor

    INewableReference<int> nr1; // NOT ALLOWED: not a reference type
    INewableReference<string> nr2; // NOT ALLOWED: no parameterless ctor
    INewableReference<MyStruct> nr3; // NOT ALLOWED: not a reference type
    INewableReference<MyClass1> nr4; // ALLOWED: has parameterless ctor
    INewableReference<MyClass2> nr5; // ALLOWED: has parameterless ctor
    INewableReference<MyClass3> nr6; // NOT ALLOWED: no parameterless ctor
    INewableReference<MyClass4> nr7; // ALLOWED: has parameterless ctor
}

1
很好的示范。谢谢。
Subhan Ali,

15

new():指定new()约束意味着类型T必须使用无参数构造函数,这样才能从该对象实例化一个对象-请参见Default构造函数

class:意味着T必须是引用类型,因此它不能是int,float,double,DateTime或其他结构(值类型)。

public void MakeCars()
{
    //This won't compile as researchEngine doesn't have a public constructor and so can't be instantiated.
    CarFactory<ResearchEngine> researchLine = new CarFactory<ResearchEngine>();
    var researchEngine = researchLine.MakeEngine();

    //Can instantiate new object of class with default public constructor
    CarFactory<ProductionEngine> productionLine = new CarFactory<ProductionEngine>();
    var productionEngine = productionLine.MakeEngine();
}

public class ProductionEngine { }
public class ResearchEngine
{
    private ResearchEngine() { }
}

public class CarFactory<TEngine> where TEngine : class, new()
{
    public TEngine MakeEngine()
    {
        return new TEngine();
    }
}



4

“ Where”之后是对您声明的泛型T的约束,因此:

  • class表示T应该是一个类,而不是值类型或结构。

  • new()表示T类应该定义一个无参数的默认默认构造函数。


1

它在通用参数T上称为“约束”。这意味着T必须是引用类型(一个类),并且它必须具有公共默认构造函数。


1

这是泛型机制的一部分,其中where关键字将约束添加到必须实现的类型中才能用作类型参数。


0

在约束中使用类时,意味着您只能使用引用类型,要添加的另一件事是何时使用约束new(),它必须是您在约束条款中写的最后一件事。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.