首页 文章

为什么我必须在使用枚举代替其基础类型时使用显式强制转换?

提问于
浏览
1
public enum Foo : byte 
{
    BAR = 0x00,
    BAZ = 0x01,
    DERP = 0xFF
}

public void AppendAsHex(StringBuilder sb, byte b)
{
    sb.AppendFormat("{0:X}", b);
}

为什么这需要一个明确的演员?

Foo theDerp = Foo.DERP;
AppendAsHex(sb, (byte)theDerp); // Fine
AppendAsHex(sb, theDerp); // Compile Error

不会发生精度损失 . 该方法声明它只需要 byte ,无视任何 enum 善良 .

编辑

如果我们将 enum 换成 byte 并使该函数采用另一种数字类型,例如:

public void AppendAsHex(StringBuilder sb, uint u)
{
    sb.AppendFormat("{0:X}", u);
}

byte b = 21;

AppendAsHex(sb, b); // Fine

因此,编译器会将数字类型提升为更大的数字类型而不会有任何麻烦,但要求强制转换使用 enum:bytebyte 执行相同操作 .

显然 enum:byte 在技术上并不是Type byte ,但是编译器肯定会看到它的类型为 System.Enum 并检查 enum 中包含的值的类型?

虽然使用复杂类型非常有意义,但编译器可能无法调整大小,在这种情况下,编译器完全了解所有内容 . 我不知道如果可以提升原语,编译器将拒绝提升/转换显式声明为基元的东西 .

这对我来说似乎不一致,我想更好地理解它 .

3 回答

  • 0

    非常简单,因为C#是强类型的 . 即使将其转换后的值设置为byte,枚举值也不是byte类型,因此必须先将其转换为byte,然后才能将其与期望类型为byte的函数一起使用 . 它与另一种类型没有什么不同 .

    此外,如果您的重点是保持清洁,您可以考虑稍微重写(或重载)您的方法,以便对其外的所有内容都不可见 . 它不会改变解决方案,但假设您将在多个地方重用该方法,则代码更少:

    public void AppendAsHex(StringBuilder sb, Foo b)
    {
        AppendAsHex(sb, (byte)b);
    }
    public void AppendAsHex(StringBuilder sb, byte b)
    {
        sb.AppendFormat("{0:X}", b);
    }
    

    在这一点上,这将工作

    Foo theDerp = Foo.DERP;
    AppendAsHex(sb, theDerp);
    
  • 2

    基础类型指定为每个枚举器分配的存储量 . 但是,从枚举类型转换为整数类型需要显式强制转换 . https://msdn.microsoft.com/en-us/library/sbbt4032(v=vs.140).aspx

    因此,尽管使用 : 来声明基础类型,但任何枚举的实际基本类型都是 System.Enum . 这就是为什么它仍然需要明确的演员 .

  • 2

    看看the answer here .

    枚举不能从System.Enum继承任何东西,所以':byte'所做的就是改变枚举值的表示方式 .

相关问题