0
votes

While learning about Generics I came to knew about Constraints on Type Parameters. One of these constraints is new() constraint. According to Microsoft:

The type argument must have a public parameterless constructor. When used together with other constraints, the new() constraint must be specified last.

Now I have a code like this.

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
        }
    }
}
  • Line 1 does not generate error bcoz classes have default parameterless constructor.
  • Line 2 does not generate error bcoz structs have default parameterless constructor. And
  • Line 3 does not generate error but WHY?

Why does new() constraint allows enum to be passed as type argument?

Also I am able to do this

E e = new E();

in the above code.

Does this mean enums have parameterless constructor by default?

Edited: After reading answers and comments I thought enums contain default constructor. So I used reflection to see if I can print on the console the default constructor of enum E. The code is as follows

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

But it doesn't prints anything.

So the question still remains Does an enum has a default parameterless constructor or not?

2
Haven't you answered your own question already? You've shown that enums do have a public parameter-less constructor.Jonathon Reinhart
But I can't explicitly define another like in a class.Learner
Enums are a class type, it's inheritance hierarchy is from System.Object and System.ValueType, it has a constructor, to read more about it: msdn.microsoft.com/en-us/library/system.enum(v=vs.110).aspxRyan Wilson
Here I am talking about the type enum not about class Enum they are both different.Learner
@RyanWilson That is not what is usually called a class type. A class type is usually taken to mean a reference type which is not an interface (sometimes not a delegate type either). In any case, an enum is a value type. But it is true that it is inheriting, in a sense, the reference type System.Enum whose base class is System.ValueType (base System.Object).Jeppe Stig Nielsen

2 Answers

4
votes

This is allowed because all specific enum types are value types. Hence, C# gives them a default constructor:

Each value type has an implicit default constructor that initializes the default value of that type.

0
votes

Every value type T is allowed with the constraint where T : new(), including every enum type.

When new T() is used, it corresponds to the zero value of the value type. It is the same as default(T) for value types.

There is a more specific constraint, where T : struct, also allowing enum types (but not Nullable<>). This constraint "implies" the where T : new() in the sense that you cannot specify both because struct automatically contains new(). Again, in the case of a value type, new T() is the same as default(T).


EDIT: To address the new question:

Does an enum has a default parameterles constructor or not?

No, in reality a value type (including an enum) does not have this zero-parameter instance constructor. But the syntax new E() is still allowed, and produces the same "zero" value as does default(E). And it is specifically permitted to use a value type for a generic parameter T constrained to where T : new().

See related thread Why default constructor does not appear for value types?