C# 即使指定了基础类型,也无法从枚举隐式转换值

C# 即使指定了基础类型,也无法从枚举隐式转换值,c#,.net,enums,C#,.net,Enums,在下面的代码示例中,我定义了一个枚举,并将其底层类型指定为byte。然后,我尝试分配一个字节值并打开枚举值,但我得到一个错误:无法将类型“CmdlnFlags”隐式转换为“byte”。存在显式转换(是否缺少转换? 守则: using System; public enum CmdlnFlags: byte { ValA = (byte)'a', ValB = (byte)'b', } public class Sample { public static void M

在下面的代码示例中,我定义了一个枚举,并将其底层类型指定为byte。然后,我尝试分配一个字节值并打开枚举值,但我得到一个错误:
无法将类型“CmdlnFlags”隐式转换为“byte”。存在显式转换(是否缺少转换?

守则:

using System;

public enum CmdlnFlags: byte {
    ValA = (byte)'a',
    ValB = (byte)'b',
}

public class Sample {
    public static void Main() {
        byte switchByte = CmdlnFlags.ValB;
        switch (switchByte) {
            case CmdlnFlags.ValA: Console.WriteLine('A'); break;
            case CmdlnFlags.ValB: Console.WriteLine('B'); break;
        }
        Console.ReadKey();
    }
}
修复很容易,只需强制转换为字节,但是如果为枚举指定了基础类型,为什么我必须强制转换呢?如果必须强制转换,那么指定基础类型有什么意义

如果我施法,一切都会成功。例如:

        byte switchByte = (byte)CmdlnFlags.ValB;
        switch (switchByte) {
            case (byte)CmdlnFlags.ValA: Console.WriteLine('A'); break;
            case (byte)CmdlnFlags.ValB: Console.WriteLine('B'); break;
        }

你必须投下,以确保这是你真正想做的。这是一种类型安全功能

您应该将枚举视为与其基础类型以及具有相同基础类型的其他枚举不同的类型。它们之间的差异很大,如果你想把它们当作另一个来使用,你需要施放

有时会让人痛苦,但最终这是件好事

不过,你为什么要在转换之前选演员呢?只需打开实际枚举值:

CmdlnFlags switchFlag = CmdlnFlags.ValB;
switch (switchFlag) {
    case CmdlnFlags.ValA: Console.WriteLine('A'); break;
    case CmdlnFlags.ValB: Console.WriteLine('B'); break;
}

在这里,您并不是真的想把这个标志当作一个字节,而是想把它当作一个标志并打开它。所以这正是你应该做的。

在大多数情况下,这样的强制转换是不必要的。不要使用
byte
类型的变量来控制开关,只需创建
CmdlnFlags
类型的变量即可

    CmdlnFlags switchValue = CmdlnFlags.ValB;
    switch (switchValue) {
         case CmdlnFlags.ValA: Console.WriteLine('A'); break;
         case CmdlnFlags.ValB: Console.WriteLine('B'); break;
     } 

这些类型转换是为了鼓励正确的程序设计。您通常不希望将枚举用作数值。

因此,从声明范围之外的视图来看,枚举没有特定的类型。必须始终强制转换枚举,除非它是普通的旧整数枚举。这是正确的吗?@Sergio:不,枚举是一种独特的类型。“超出声明范围”到底是什么意思?代码段只是我在代码段编译器中快速生成的,用于快速显示一些场景+将枚举看作单独的类型是一个很好的观点。尽管我仍然不明白,如果你以后不得不小心翼翼地处理它,那么指定一个底层类型有什么意义?@Paul:把它想象成一个只有一个底层类型字段的结构。它与基础类型不同,但这决定了它可以存储什么。@Joshua:为什么不使用两个属性,都公开相同的数据,但其中一个具有对枚举类型的强制转换?然后你会有一个单一的每个属性,而不是它“乱丢”你的代码库。