带乘法条件的 switch 语句 [已解决]

问题描述

我有这样的代码

switch (array[0],array[1],array[2])
{
    case (EntityRoute.north,EntityRoute.West,EntityRoute.south):
        prohibitedRoute = EntityRoute.East;
        return true;
    
    case (EntityRoute.south,EntityRoute.north):
        prohibitedRoute = EntityRoute.East;
        return true;
    
    case (EntityRoute.north,EntityRoute.East,EntityRoute.south):
        prohibitedRoute = EntityRoute.West;
        return true;
    
    case (EntityRoute.south,EntityRoute.north):
        prohibitedRoute = EntityRoute.West;
        return true;
    
    case (EntityRoute.south,EntityRoute.north):
        prohibitedRoute = EntityRoute.West;
        return true;
}

我想做一个条件顺序不严格的系统。是否有任何选项可以在不编写其他案例的情况下进行此操作?请注意,我使用的是 C# 8.0,因为我使用的是 Unity3D。

解决方法

不需要 switch 语句。试试这个:

EntityRoute[] all = new [] { EntityRoute.North,EntityRoute.East,EntityRoute.South,EntityRoute.West,};
EntityRoute[] array = new [] { EntityRoute.East,EntityRoute.North,};
EntityRoute prohibitedRoute = all.Except(array).First();
Console.WriteLine(prohibitedRoute.ToString());

这给了我:

West

您甚至可以这样定义 all

EntityRoute[] all = Enum.GetValues(typeof(EntityRoute)).Cast<EntityRoute>().ToArray();
,

不,没有与您想要的相似(检查单个 switch 多个对象)。

最接近的是 c# 8.0 中引入的 switch expression,但它不会同时检查多个变量。

检查 CSharphie's answer 最终建议为什么,如果您将枚举标记为 Flags,真的不需要 switch 语句。

,

您可以使用 Tuple Patterns,它是 C# 8.0 的一部分

如下图

EntityRoute? prohibitedRoute = (array[0],array[1],array[2]) switch
        {
            (EntityRoute.North,EntityRoute.South) => EntityRoute.East,(EntityRoute.South,EntityRoute.North) => EntityRoute.East,(EntityRoute.North,EntityRoute.South) => EntityRoute.West,EntityRoute.North) => EntityRoute.West,_ => null
        };
,

如果您不想使用标志,您也可以在实际检查之前对您的值进行排序:

// Copy array to keep original values. Only needed if you need to access the original order later
var orderedArray = array.Copy();
Array.Sort(orderedArray);

switch (orderedArray[0],orderedArray[1],orderedArray[2])
{
    // Write your cases according to the values of your enum here
}

我认为这个解决方案是您实际问题的答案。

在您的具体情况下,我更喜欢 Enigmativity 的解决方案。

,

假设这是一个 Enum 并且标有 Flags(技术上没有必要),您可以这样做:

[Flags]
public enum EntityRoute
{
   North = 1,East = 2,South = 4,West = 8
}

您必须确保值是唯一的,因此枚举值的顺序无关紧要,Noth | East | SouthEast | North | South 相同,因此它只能出现一次。

switch (array[0] | array[1] | array[2])
{
    case EntityRoute.North | EntityRoute.West | EntityRoute.South:
        prohibitedRoute = EntityRoute.East;
        return true;
            
    ....
}

请记住,这仅在 Enum 设置了正确的值(即 2 的幂)时才能正常工作。

但是,您不需要数组来存储值:

something = EntityRoute.South | EntityRoute.East;
...
something |= EntityRoute.South

我建议您阅读有关 c# 中标志枚举的主题。 https://stackoverflow.com/a/8480/1789202

然后你最终会发现你甚至不需要这个开关盒,如果你总是有 3 个方向,结果是缺少一个。