我已经编写了以下代码,并且已成功编译。
class Program
{
enum Fruits
{
Apple,
Mango,
Banana
}
static void Main(string[] args)
{
Fruits f = new Fruits();
}
}
尽管Fruits
是enum
,编译器和解释器允许我写这个。这是否意味着我可以为枚举创建构造函数?如果是,那怎么样?
答案 0 :(得分:5)
不,你不能。
new Fruits()
将返回默认值(枚举的基础类型中与0
对应的值),它与default(Fruits)
(或Fruits.Apple
相同情况)。
请记住,枚举只是基本类型的包装(默认情况下为int
)。您可以将new Fruits()
与new int()
进行比较。
通常您不使用new Fruits()
/ new int()
语法,因为更常见的是只写0
或default(T)
,但您可能希望在通用中使用它码。举个例子:
public T NewInstance<T>()
where T : new()
{
return new T();
}
您可以致电NewInstance<Fruits>()
,这将返回Fruits.Apple
。
答案 1 :(得分:3)
枚举类型是具有一组命名常量的不同值类型。
至于默认值(如另一个答案中所述):
任何枚举类型的默认值是整数值零 转换为枚举类型。在变量是自动的情况下 初始化为默认值,这是给变量的值 枚举类型。为了枚举类型的默认值 容易获得,文字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
然而:
struct
或class
的类型添加新的构造函数,因此就值类型而言,只能struct
。在enum
s和原语的情况下,构造函数甚至不被声明。
因此,你无法创建这样的构造函数。
(严格来说,.NET确实允许你在struct
上设置一个已定义的无参数构造函数,但是C#没有,如果你在原始CIL中执行它,那么什么时候会有不一致的规则被调用,当你刚刚创建了一个全零实例时。)