我修改了Thorarin在回答这个问题时给出的扩展方法,以处理int而不是字符串:
public static TEnum ToEnum<TEnum>(this int intEnumValue, TEnum defaultValue)
{
if (!Enum.IsDefined(typeof(TEnum), intEnumValue))
return defaultValue;
return (TEnum)intEnumValue;
}
Run Code Online (Sandbox Code Playgroud)
编译器给出错误"无法将类型'int'转换为'TEnum'." 在最后一行.
如果该行更改为:
return (TEnum)(object)intEnumValue;
Run Code Online (Sandbox Code Playgroud)
它编译和工作.
为什么首先需要将int转换为object?
直接int转换为未知类型是不可能的,因此编译器不允许(TEnum)intEnumValue.你现在正在做的两个演员实际上是微妙的不同:(object)盒子int,当(TEnum)盒装int到一个TEnum,这是静态允许的,因为静态类型的表达式object实际上可能是运行时类型TEnum.
可能还有一些进一步的细微之处:通常情况下,盒装int 只能取消装箱int.我想我已经解释了为什么编译器允许转换,但不解释为什么运行时也允许转换.也许转换到TEnum只允许在运行时,因为TEnum恰好是一个具有int基本类型的枚举?我想我记得读过CLR中的枚举实际上只是它们基类型的实例.
编辑:我证实了我的怀疑:
public static void Main()
{
int value = 1;
IntEnum i = ToEnum<IntEnum>(value); // Valid cast, runs fine.
ByteEnum b = ToEnum<ByteEnum>(value); // Invalid cast exception!
}
public enum ByteEnum : byte { }
public enum IntEnum : int { }
public static TEnum ToEnum<TEnum>(int value)
{
return (TEnum)(object)value;
}
Run Code Online (Sandbox Code Playgroud)
因此,我们可以肯定地说,(TEnum)在盒装int只有当有效的TEnum实际上是一个int被窝里!