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

问题描述 投票:0回答:2

在学习泛型的过程中,我开始了解类型参数的约束。其中一个约束是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());
}

但它不会打印任何东西。

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

c# .net generics
2个回答
3
投票

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

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


0
投票

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

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

有一个更具体的约束,where T : struct,也允许枚举类型(但不是Nullable<>)。由于where T : new()自动包含struct,因此该约束“暗示”new(),因为您无法指定两者。同样,在值类型的情况下,new T()default(T)相同。


编辑:解决新问题:

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

不,实际上值类型(包括枚举)没有这个零参数实例构造函数。但仍然允许使用语法new E(),并产生与default(E)相同的“零”值。并且特别允许将值类型用于约束到T的通用参数where T : new()

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

© www.soinside.com 2019 - 2024. All rights reserved.