【问题标题】:Unable to implicitly convert value from enum even though the underlying type is specified即使指定了基础类型,也无法从枚举隐式转换值
【发布时间】:2011-04-11 18:39:43
【问题描述】:

在下面的代码示例中,我定义了一个枚举并将其基础类型指定为字节。然后我尝试分配一个字节值并打开枚举的值,但出现错误:Cannot implicitly convert type 'CmdlnFlags' to 'byte'. An explicit conversion exists (are you missing a cast?)

代码:

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;
        }

【问题讨论】:

    标签: c# .net enums


    【解决方案1】:

    您必须进行投射以确保这确实是您的意思。这是一种类型安全功能。

    您应该将枚举视为与其基础类型不同的类型 - 以及与具有相同基础类型的其他枚举不同的类型。它们完全不同,如果您想将一个用作另一个,则需要进行投射。

    这有时会很痛苦,但最终它是一件好事。

    你为什么要在切换之前施放呢?只需打开实际的枚举值:

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

    在这里,您真的不想将标志视为一个字节 - 您想将其视为一个标志并打开它。所以这正是你应该做的。

    【讨论】:

    • 所以从声明范围之外的角度来看,枚举没有特定的类型。您必须始终强制转换枚举,除非它是一个普通的旧整数枚举。这是正确的吗?
    • @Sergio:不,枚举是一种不同的类型。 “声明范围之外”到底是什么意思?
    • 代码 sn-p 只是我在 Snippet Compiler 中快速展示一些场景的东西。 +1 关于将枚举视为单独类型的要点。虽然我仍然不明白指定底层类型的意义,如果你以后必须带着孩子手套来处理它?
    • @Paul:把它想象成一个结构体,只有一个底层类型的字段。它与底层类型不同,但这决定了它可以存储什么。
    • @Joshua:为什么不拥有两个属性,它们都暴露相同的数据,但一个对枚举类型进行强制转换?然后,您将拥有一个每个属性,而不是“乱扔”您的代码库。
    【解决方案2】:

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

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

    需要演员表来鼓励正确的程序设计。您通常不希望将枚举用作数值。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-01-13
      • 1970-01-01
      • 2022-12-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多