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

时间:2016-07-01 02:19:37

标签: c# types enums casting byte

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 :(得分:2)

非常简单,因为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);

答案 1 :(得分:2)

  

基础类型指定为每个存储分配多少存储空间   枚举。但是,转换必须使用显式转换   枚举类型为整数类型。

     

https://msdn.microsoft.com/en-us/library/sbbt4032(v=vs.140).aspx

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

答案 2 :(得分:0)

查看the answer here

枚举不能继承任何东西,除了System.Enum所以所有的':字节'正在做的是改变枚举值的表示方式。