为什么new()约束允许枚举作为c#中的类型参数?

时间:2018-03-03 16:17:28

标签: c# .net generics

在了解泛型时,我开始了解对类型参数的约束。 其中一个约束是 new()约束。根据微软的说法:

  

type参数必须具有公共无参数构造函数。什么时候   与其他约束一起使用时,new()约束必须是   最后指定。

现在我有了这样的代码。

using System;

namespace Test
{
    class A { }

    struct S { }

    enum E { }

    class Generics
    {
        public static void GenericMethod<T>() where T : new() 
        {
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            Generics.GenericMethod<A>(); // Line 1
            Generics.GenericMethod<S>(); // Line 2
            Generics.GenericMethod<E>(); // Line 3
        }
    }
}
  • 第1行不生成错误bcoz类具有默认无参数 构造
  • 第2行不会产生错误bcoz结构具有默认无参数 构造函数。和
  • 第3行不会产生错误,但为什么?

为什么new()约束允许枚举作为类型参数传递?

我也能做到这一点

E e = new E();

在上面的代码中。

这是否意味着默认情况下枚举具有无参数构造函数?

已编辑:在阅读答案和评论后,我认为枚举包含默认构造函数。所以我用反射看看我是否可以在控制台上打印枚举E的默认构造函数。代码如下

Type T = typeof(E);
Console.WriteLine("Constructors");
ConstructorInfo[] constructors = T.GetConstructors();
foreach (var constructor in constructors)
{
    Console.WriteLine(constructor.ToString());
}

但它不会打印任何东西。

所以问题仍然存在枚举是否有默认的无参数构造函数?

2 个答案:

答案 0 :(得分:3)

这是允许的,因为所有特定的枚举类型都是value types。因此,C#为它们提供了一个默认构造函数:

  

每个值类型都有一个隐式默认构造函数,用于初始化该类型的默认值。

答案 1 :(得分:0)

约束T允许使用每个值类型where T : new(),包括每个枚举类型。

使用new T()时,它对应于值类型的零值。对于值类型,它与default(T)相同。

还有一个更具体的约束,where T : struct,也允许枚举类型(但不是Nullable<>)。这种约束&#34;意味着&#34; where T : new()因为struct自动包含new()而无法同时指定这两者。同样,对于值类型,new T()default(T)相同。

编辑:要解决新问题:

  

枚举是否有默认参数构造函数?

不,实际上,值类型(包括枚举)没有此零参数实例构造函数。但是仍然允许语法new E(),并产生相同的&#34;零&#34;价值与default(E)一样。并且特别允许将值类型用于约束为T的通用参数where T : new()

参见相关主题Why default constructor does not appear for value types?