Reputation: 19591
I have written below code and it's compiling successfully.
class Program
{
enum Fruits
{
Apple,
Mango,
Banana
}
static void Main(string[] args)
{
Fruits f = new Fruits();
}
}
Despite of Fruits
being an enum
, compiler and interpreter are allowing me to write this. Does this mean I can create a constructor for an enum? if yes then how?
Upvotes: 10
Views: 14808
Reputation: 51330
No, you can't.
new Fruits()
will return the default value (the value corresponding to 0
in the underlying type of the enum), it's the same as default(Fruits)
(or Fruits.Apple
in your case).
Remeber that enums are only wrappers around a primitive type (int
by default). You can pretty much compare new Fruits()
to new int()
.
Usually you don't use the new Fruits()
/new int()
syntax as it's more common to just write 0
or default(T)
, but you may want to use it in generic code. As an example:
public T NewInstance<T>()
where T : new()
{
return new T();
}
You are allowed to call NewInstance<Fruits>()
, which will return Fruits.Apple
.
Upvotes: 7
Reputation: 6141
An enum type is a distinct value type with a set of named constants.
As for the default value (as explained in the other answer):
The default value of any enum type is the integral value zero converted to the enum type. In cases where variables are automatically initialized to a default value, this is the value given to variables of enum types. In order for the default value of an enum type to be easily available, the literal 0 implicitly converts to any enum type.
Move the default constant to be the first in your enum.
Upvotes: 4
Reputation: 113222
For any value type, there is a parameterless constructor that returns the all-zero value. Hence:
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
However:
struct
or a class
, and so as far as value-types go, only struct
.In the case of enum
s and primitives the constructor isn't even declared.
Hence you can't create such a constructor.
(Strictly speaking, .NET does allow you to set a defined parameterless constructor on a struct
but C# doesn't, and if you do it in raw CIL there are inconsistent rules as to when it will be called and when you'll just get an all-zero instance created).
Upvotes: 1
Reputation: 8785
No. Check out the IL output (generated in LINQPad). It's not actually calling a constructor at all. Instead, it's storing the integer value 0 inside a local variable called f
. This is the exact same output as you get when you use a type cast to the enum.
As far as the compiler is concerned, Fruits f = new Fruits();
is the same as 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
For comparison, here's the IL output of a normal class. Look at IL_001 under Program.Main where it actually calls a constructor for the class.
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
Upvotes: 1