“where T : class, new()”是啥意思?

Posted

技术标签:

【中文标题】“where T : class, new()”是啥意思?【英文标题】:What does "where T : class, new()" mean?“where T : class, new()”是什么意思? 【发布时间】:2011-01-19 16:37:42 【问题描述】:

您能否向我解释一下where T : class, new() 在以下代码行中的含义?

void Add<T>(T item) where T : class, new();

【问题讨论】:

供以后使用:msdn.microsoft.com/en-us/library/d5x73970.aspx 【参考方案1】:

这是对泛型参数T 的约束。它必须是class(引用类型)并且必须有一个公共的无参数默认构造函数。

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

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

【讨论】:

澄清一下,如果您没有将 class 子句作为 where T... 的一部分,那么使用 int、float、double 等是安全的。 @AboutDev 正确,您不必对泛型类型参数施加约束。但是,如果您正在创建一个只适用于引用或值类型的泛型,那么您应该指定。如果没有约束,您可以期望引用类型(类)或值类型(结构(int、float、double...))。 哪里 T : [接口名称], new() 呢?你还需要一个无参数的构造函数吗? 为了澄清贾斯汀的评论,空构造函数没有语句(如默认构造函数),而无参数构造函数可能包含语句(如初始化列表)。 @VinceTino: new() 精确指定“必须有一个公共的无参数构造函数”【参考方案2】:

这些是泛型类型约束。在您的情况下,有两个:

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); 我认为在哪里说 T : class, new() 是多余的,因为 new() 已经暗示了 class,因为结构不能有默认构造函数。 @DharmaTurtle,“结构不能包含显式的无参数构造函数”,并不意味着它们没有,而是说你不能定义一个。来源:msdn.microsoft.com/tr-tr/library/aa288208(v=vs.71).aspx【参考方案3】:

其中 T : 结构

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

其中 T:类

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

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

其中 T : [基类名称]

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

其中 T : [接口名称]

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

其中 T : U

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

【讨论】:

这很有用,但是link to source。【参考方案4】:

class & new 是 2 constraints on the generic type parameter T。 他们分别确保:

class

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

new

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

它们的组合意味着T类型必须是Reference Type(不能是Value Type),并且必须有一个无参数的构造函数。

例子:

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

【讨论】:

很好的示范。谢谢。【参考方案5】:

new(): 指定 new() 约束意味着类型 T 必须使用无参数构造函数,因此可以从中实例化对象 - 参见 Default constructors。

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();
    

【讨论】:

【参考方案6】:

这意味着T 类型必须是一个类并且有一个不带任何参数的构造函数。

例如,您必须能够做到这一点:

T t = new T();

【讨论】:

不只是一个构造函数,而是一个不带参数的构造函数。 @NerdFury:谢谢。这是很重要的一点。已更正。【参考方案7】:

where (C# Reference)

new() 约束让编译器知道提供的任何类型参数都必须具有可访问的无参数(或默认)构造函数

所以它应该是,T 必须是一个类,并且有一个可访问的无参数 - 或默认构造函数。

【讨论】:

【参考方案8】:

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

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

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

【讨论】:

【参考方案9】:

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

【讨论】:

【参考方案10】:

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

【讨论】:

【参考方案11】:

在约束中使用class意味着你只能使用Reference类型,另外要补充一点是什么时候使用约束new(),它必须是你在约束条件中写的最后一件事。

【讨论】:

以上是关于“where T : class, new()”是啥意思?的主要内容,如果未能解决你的问题,请参考以下文章

财富的涵义

H5 文本属性

珊仑怖未耙耘阅

霸藕咽诎旧良采

懦忌嗣腾闭油馗

非俺毙刃滴汛筛