我可以为Enum创建构造函数吗?

时间:2015-08-05 14:10:01

标签: c# .net

我已经编写了以下代码,并且已成功编译。

class Program
{
        enum Fruits
        {
            Apple,
            Mango,
            Banana
        }

        static void Main(string[] args)
        {
            Fruits f = new Fruits();
        }
}

尽管Fruitsenum,编译器和解释器允许我写这个。这是否意味着我可以为枚举创建构造函数?如果是,那怎么样?

4 个答案:

答案 0 :(得分:5)

不,你不能。

new Fruits()将返回默认值(枚举的基础类型中与0对应的值),它与default(Fruits)(或Fruits.Apple相同情况)。

请记住,枚举只是基本类型的包装(默认情况下为int)。您可以将new Fruits()new int()进行比较。

通常您不使用new Fruits() / new int()语法,因为更常见的是只写0default(T),但您可能希望在通用中使用它码。举个例子:

public T NewInstance<T>()
    where T : new()
{
    return new T();
}

您可以致电NewInstance<Fruits>(),这将返回Fruits.Apple

答案 1 :(得分:3)

C# Spec

  

枚举类型是具有一组命名常量的不同值类型。

至于默认值(如另一个答案中所述):

  

任何枚举类型的默认值是整数值零   转换为枚举类型。在变量是自动的情况下   初始化为默认值,这是给变量的值   枚举类型。为了枚举类型的默认值   容易获得,文字0隐式转换为任何枚举类型。

将默认常量移动到枚举中的第一个。

答案 2 :(得分:1)

没有。检查IL输出(在LINQPad中生成)。它根本不是在调用构造函数。相反,它将整数值0存储在名为f的局部变量中。这是与使用枚举类型转换时得到的完全相同的输出

就编译器而言,Fruits f = new Fruits();Fruit f = (Fruit)0;相同。

Fruits f = new Fruits() IL

Program.Main:
IL_0000:  nop         
IL_0001:  ldc.i4.0    
IL_0002:  stloc.0     // f
IL_0003:  ret         

Program..ctor:
IL_0000:  ldarg.0     
IL_0001:  call        System.Object..ctor
IL_0006:  ret   

为了比较,这是普通类的IL输出。查看Program.Main下的IL_001,它实际上调用了该类的构造函数。

Program.Main:
IL_0000:  nop         
IL_0001:  newobj      UserQuery+Program+Fruits..ctor
IL_0006:  stloc.0     // f
IL_0007:  ret         

Program..ctor:
IL_0000:  ldarg.0     
IL_0001:  call        System.Object..ctor
IL_0006:  ret         

Fruits..ctor:
IL_0000:  ldarg.0     
IL_0001:  call        System.Object..ctor
IL_0006:  ret         

答案 3 :(得分:1)

对于任何值类型,都有一个无参数构造函数,它返回全零值。因此:

var val = new int(); // 0
var val = new double(); // 0.0
var val = new DateTime(); // 0001-01-01T00:00:00.000000 Unspecified timezone
var val = new StringSplitOptions(); // StringSplitOptions.None

然而:

  1. 您无法为不是structclass的类型添加新的构造函数,因此就值类型而言,只能struct
  2. 您无法更改任何这些默认构造函数的实现。
  3. enum s和原语的情况下,构造函数甚至不被声明。

    因此,你无法创建这样的构造函数。

    (严格来说,.NET确实允许你在struct上设置一个已定义的无参数构造函数,但是C#没有,如果你在原始CIL中执行它,那么什么时候会有不一致的规则被调用,当你刚刚创建了一个全零实例时。)