I was reading the following SO post about Type Safe Enum, and was wondering about the reason to use int
internally instead of simply Enum:
So I decided to write the following code:
public readonly struct TypeSafeEnum
{
private readonly int Value { get; init; } /* implementation detail */
public readonly string Name { get; init; }
public static readonly TypeSafeEnum Foo = new TypeSafeEnum { Value = Enum.Foo, Name = nameof(Enum.Foo) };
public static readonly TypeSafeEnum Bar = new TypeSafeEnum { Value = Enum.Bar, Name = nameof(Enum.Bar) };
public class Enum
{
public const int Foo = 1;
public const int Bar = 2;
}
public static implicit operator int(TypeSafeEnum vr) => vr.Value;
};
Which works well in something like:
bool test(TypeSafeEnum tse)
{
switch (tse)
{
case TypeSafeEnum.Enum.Foo:
case TypeSafeEnum.Enum.Bar:
return true;
}
return false;
}
Now let's see what happen if we change the implementation detail of this type safe enum using this time an enum internally:
public readonly struct TypeSafeEnum2
{
private readonly Enum Value { get; init; } /* implementation detail */
public readonly string Name { get; init; }
public static readonly TypeSafeEnum2 Foo = new TypeSafeEnum2 { Value = Enum.Foo, Name = nameof(Enum.Foo) };
public static readonly TypeSafeEnum2 Bar = new TypeSafeEnum2 { Value = Enum.Bar, Name = nameof(Enum.Bar) };
public enum Enum
{
Foo,
Bar
}
public static implicit operator Enum(TypeSafeEnum2 vr) => vr.Value;
};
Now the example above give the following error:
Cannot implicitly convert type 'TypeSafeEnum2.Enum' to 'TypeSafeEnum2'
For reference:
bool test(TypeSafeEnum2 tse)
{
//switch ((TypeSafeEnum2.Enum)tse)
switch (tse)
{
case TypeSafeEnum2.Enum.Foo:
case TypeSafeEnum2.Enum.Bar:
return true;
}
return false;
}
Why in the first case switch
natively support implicit conversion to int
, but does not support implicit conversion to enum
in the second case (requires explicit conversion) ?