泛型扩展中的Int cast错误

2 c# generics casting

我修改了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?

Jor*_*ren 5

直接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被窝里!