I am surprised that the following code passes PEVerify (Version 4.0.30319.1) and runs OK, outputting True and 0. This enum definition violates ECMA-335 6th ed. §II.14.3.
.class private auto ansi sealed EnumFloat.EFlo
extends [mscorlib]System.Enum
{
.field public specialname rtspecialname float32 value__
.field public static literal valuetype EnumFloat.EFlo GG = float32(24.25)
} // end of class EnumFloat.EFlo
.class private abstract auto ansi sealed beforefieldinit EnumFloat.Program
extends [mscorlib]System.Object
{
.method private hidebysig static void Main(string[] args) cil managed
{
.entrypoint
.maxstack 8
.locals init (
[0] valuetype EnumFloat.EFlo f,
[1] class [mscorlib]System.Enum e)
ldc.r4 24.25
stloc.0
ldloc.0
box EnumFloat.EFlo
stloc.1
ldloc.1
ldloc.1
callvirt instance bool [mscorlib]System.Object::Equals(object)
call void [mscorlib]System.Console::WriteLine(bool)
ldloc.1
ldloc.1
call instance int32 [mscorlib]System.Enum::CompareTo(object)
call void [mscorlib]System.Console::WriteLine(int32)
ret
} // end of method Program::Main
} // end of class EnumFloat.ProgramIn the CoreCLR source, the underlying type of the enum is validated in by RegMeta::ValidateTypeDef, which explicitly allows ELEMENT_TYPE_R4 and ELEMENT_TYPE_R8. So does ReflectionEnum::InternalCompareTo, which is used in Enum.CompareTo.
Enum.ToString however does not work:
Unhandled Exception: System.ArgumentException: The value passed in must be an en um base or an underlying type for an enum, such as an Int32. Parameter name: value at System.RuntimeType.GetEnumName(Object value) at System.Enum.GetName(Type enumType, Object value) at System.Enum.InternalFormat(RuntimeType eT, Object value) at System.Enum.ToString() at System.Enum.ToString(String format) at System.Enum.ToString(String format, IFormatProvider provider) at System.IO.TextWriter.WriteLine(Object value) at System.IO.TextWriter.SyncTextWriter.WriteLine(Object value) at EnumFloat.Program.Main(String[] args)