如果类型T需要实例化,为什么泛型类签名需要指定new()?

thi*_*eek 13 c# generics

我正在写一个Generic类,如下所示.

public class Foo<T> : 
    where T : Bar, new()
{
    public void MethodInFoo()
    {
        T _t = new T();
    }
}
Run Code Online (Sandbox Code Playgroud)

如您所见,_tT类型的对象在运行时被实例化.为了支持泛型类型T的实例化,语言强制我将new()放在类签名中.如果Bar是一个抽象类,我同意这个,但是如果Bar标准的非抽象类具有公共无参数构造函数,为什么需要这样.

如果未找到new(),编译器将提示以下消息.

无法创建变量类型"T"的实例,因为它没有new()约束

Rub*_*ink 22

因为通常不会假设模板参数需要[非抽象和]可构造[通过公共无参数构造函数],以便Type匹配模板参数定义.

:new()在模板上添加约束之前:

  • 编译器不会让你构造一个 T
  • 编译器将允许您T与抽象类型或类型匹配,而无需公共无参数构造函数

:Bar位是正交的,意味着:

  • 不要让人们匹配不是来自[或是]的类型 Bar
  • 让我投Ts到Bar或派生类型Bar体内
  • 让我叫的公开及内部范围的方法,BarT

  • 我不喜欢措辞"默认构造函数",因为在某些情况下可能不清楚.我更喜欢它:添加`,new()`强制用户代码使用具有*no-argument*构造函数的泛型类型参数. (3认同)
  • @Kobi:默认构造函数的定义略宽,可以认为是包含所有参数的默认值的构造函数等.此外,像转换运算符这样的东西开始被考虑(在读者的头脑中).我最初回答的一个关键点是它必须是"公共"的事实. (2认同)

Aak*_*shM 11

仅仅因为Bar类定义了一个无参数的构造函数,并不意味着所有的东西Bar都会这样做 - 可能有一个继承自Bar但隐藏无参数构造函数的类.这样的类会满足Bar约束,但正确地使new()约束失败.

(请注意,如果您Bar sealed要避免这种可能性,您可以(可以理解)不再将其用作通用约束) - 编辑尝试此操作会产生编译器错误CS0701.