代码之家  ›  专栏  ›  技术社区  ›  Antoine Thiry Esther L

C#使用多个键为相同值打开枚举

  •  2
  • Antoine Thiry Esther L  · 技术社区  · 6 年前

    我已经搜索了如何在C#中切换值而不是枚举键,但没有结果,我找到的所有帖子都说我们不需要使用值,我们可以只使用键。

    但在我的例子中,我想使用该值,因为我创建了一个枚举,其中多个键共享相同的值,下面是代码:

    public enum PlayerPosition {
        North = 0,
        Top = 0, 
        South = 1,
        Bottom = 1,
        East = 2,
        Right = 2,
        West = 3,
        Left = 3
    }
    
    
    switch (obj.PlayerPosition)
    {
        case PlayerPosition.North:
            // some code
            break;
        case PlayerPosition.South:
            // some code
            break;
        case PlayerPosition.East:
            // some code
            break;
        case PlayerPosition.West:
            // some code
            break;
        default:
            throw new ArgumentOutOfRangeException();
    }
    

    我认为这是可行的,但我不觉得它真的可读。。。

    我想要实现的是:

    switch (obj.PlayerPosition)
    {
        case PlayerPosition.Top:
        case PlayerPosition.North:
            // some code
            break;
        case PlayerPosition.Bottom:
        case PlayerPosition.South:
            // some code
            break;
        case PlayerPosition.Right:
        case PlayerPosition.East:
            // some code
            break;
        case PlayerPosition.Left:
        case PlayerPosition.West:
            // some code
            break;
        default:
            throw new ArgumentOutOfRangeException();
    }
    

    上面的示例不起作用,因为它是重复的案例标签。 我怎样才能做到这一点?

    编辑 :在此枚举中,北/上、南/下是完全相同的,它们仅表示玩家在一张有4把椅子的桌子周围的位置。但我们有使用北/南/东/西的旧配置文件和使用上/下/右/左的新配置文件。

    5 回复  |  直到 6 年前
        1
  •  2
  •   Fildor    6 年前

    我在一个 dotnetfiddle :仅使用新成员即可:

    public enum MyEnum
    {
        North  = 0, //old
        Top    = 0, //new
        South  = 1, //old
        Bottom = 1  //new
    }
    
    public static void Main()
    {
        // Parse "old" from XML config (simulated)
        MyEnum test = (MyEnum)Enum.Parse(typeof(MyEnum),"North");
        //          = MyEnum.North
    
        switch(test)
        {
            case MyEnum.Top:
                Console.WriteLine("NORTH");
                break;
            case MyEnum.Bottom:
                Console.WriteLine("SOUTH");
                break;
            default:
                Console.WriteLine("Unsupported!");
                break;
    
        }
    }
    

    将输出“北”。

    编辑

    只是说说实际情况 问题 您面临的是:向下兼容性。 我要做的是在启动时检查配置是否与当前程序版本兼容。如果没有:请执行“升级”功能(保存旧配置的备份,然后)将配置转换为当前版本并将其保存回磁盘。

        2
  •  2
  •   William Nolan    3 年前

    关于不使用具有相同值的多个枚举标签的问题。总的来说,我同意。然而,在某些情况下,你可以说这确实有一定的道理。中的以下枚举。NET系统。图形库就是一个示例:

      public enum RotateFlipType
      {
        Rotate180FlipXY = 0,
        RotateNoneFlipNone = 0,
        Rotate270FlipXY = 1,
        Rotate90FlipNone = 1,
        Rotate180FlipNone = 2,
        RotateNoneFlipXY = 2,
        Rotate270FlipNone = 3,
        Rotate90FlipXY = 3,
        Rotate180FlipY = 4,
        RotateNoneFlipX = 4,
        Rotate270FlipY = 5,
        Rotate90FlipX = 5,
        Rotate180FlipX = 6,
        RotateNoneFlipY = 6,
        Rotate270FlipX = 7,
        Rotate90FlipY = 7,
      }
    

    此枚举用于表示要对图像执行的旋转或“翻转”类型。请注意,有些值是相同的,例如,旋转180度相当于翻转X轴和Y轴。

    即使在本例中,也可能有其他方法来表示枚举而不复制值,但此方法可能是最方便用户的方法。

    我不认为复制值有任何内在的错误,事实上它是受支持的。但是,您无法在switch语句等结构中使用这些重复的枚举值。

        3
  •  1
  •   Mark Benningfield    6 年前

    您应该修改配置文件的解析器,以便在它成为问题之前解决这个问题。

    您的程序一次只能有一个版本。按照现在的方式,您有两个版本的配置文件,并且您试图同时维护两个版本的代码。

    处理旧版本配置文件的常规方法是在读取数据时将其转换为新格式,或者在第一次打开数据时检测数据并将其在磁盘上转换为新版本(可以选择通知用户)。

        4
  •  0
  •   Steve Harris    6 年前

    不能对枚举执行此操作。枚举的目的是使每个项具有不同的值,并且可以与其他项区分开来。为什么你会让Top和North是同一件事,而你可以总是使用North,避免另外有Top的混淆?我个人只会选择北、南、东和西,然后去掉其他的。

    然而,据我所知,这应该是可行的:

    public enum PlayerPosition {
        North,
        Top, 
        South,
        Bottom,
        East,
        Right,
        West,
        Left
    }
    
    switch (obj.PlayerPosition)
    {
        case PlayerPosition.Top:
        case PlayerPosition.North:
            // some code
            break;
        case PlayerPosition.Bottom:
        case PlayerPosition.South:
            // some code
            break;
        case PlayerPosition.Right:
        case PlayerPosition.East:
            // some code
            break;
        case PlayerPosition.Left:
        case PlayerPosition.West:
            // some code
            break;
        default:
            throw new ArgumentOutOfRangeException();
    }
    
        5
  •  0
  •   Hoots    6 年前

    如果没有两个单独的枚举,我无法理解为同一个枚举值使用两个不同标签的原因。首先要回答您的问题,您可以将枚举值强制转换为int,然后对int进行比较。。。

    int value =  (int)obj.PlayerPosition
    

    但我可能会考虑删除重复的值并使用两个枚举

    public enum PlayerPosition {
        Top = 0, 
        Bottom = 1,
        Right = 2,
        Left = 3
    }
    
    public enum CompassPosition {
        North = 0, 
        South= 1,
        East= 2,
        West = 3
    }
    

    如果你想在两者之间转换,你可以直接进行转换,例如:。

    PlayerPosition pos = PlayerPosition.Left;
    CompassPosition compass = (CompassPosition)pos;
    Console.WriteLine(compass.ToString());