If I have a generic interface with a struct
constraint like this:
public interface IStruct<T> where T : struct { }
I can supply an enumeration as my type T
like so, because an enum
satisfies a struct
constraint:
public class EnumIsAStruct : IStruct<DateTimeKind> { }
C# 7.3 added an Enum
constraint. The following code, which was previously illegal, now compiles:
public class MCVE<T> : IStruct<T> where T : struct, Enum { }
However, to my surprise, the following fails to compile:
public class MCVE<T> : IStruct<T> where T : Enum { }
...with the error
CS0453 The type 'T' must be a non-nullable value type in order to use it as parameter 'T' in the generic type or method 'IStruct'
Why is this? I would expect a generic type constrained by Enum
to be usable as a type argument where the type is constrained by struct
but this doesn't seem to be the case - I am having to change my Enum
constraint to struct, Enum
. Is my expectation wrong?
This issue is strange (arguably), but expected, behavior.
The class
System.Enum
itself could be supplied as the type ofT
. Being a class,System.Enum
is of course not astruct
!As explained by contributor HaloFour:
The solution is to make it your standard practice to constrain to
struct, Enum
when you wish to constrain concrete types to being any specific enumeration. If additionally you wish to accept the classSystem.Enum
as your generic type, only then would you constrain toEnum
.