具有多个条件的 switch 语句
Switch statement with multiply conditions
我有这样的代码:
switch (array[0], array[1], array[2])
{
case (EntityRoute.North, EntityRoute.West, EntityRoute.South):
prohibitedRoute = EntityRoute.East;
return true;
case (EntityRoute.South, EntityRoute.West, EntityRoute.North):
prohibitedRoute = EntityRoute.East;
return true;
case (EntityRoute.North, EntityRoute.East, EntityRoute.South):
prohibitedRoute = EntityRoute.West;
return true;
case (EntityRoute.South, EntityRoute.East, EntityRoute.North):
prohibitedRoute = EntityRoute.West;
return true;
case (EntityRoute.South, EntityRoute.East, EntityRoute.North):
prohibitedRoute = EntityRoute.West;
return true;
}
我想做一个条件顺序不严格的系统。有没有办法在不编写额外案例的情况下做到这一点?请注意我使用的是 C# 8.0,因为我在 Unity3D 中工作。
假设这是一个 Enum
并且它被标记为 Flags
(技术上它不是必需的)你可以这样做:
[Flags]
public enum EntityRoute
{
North = 1,
East = 2,
South = 4,
West = 8
}
不过您必须确保值是唯一的,因此枚举值的顺序无关紧要,Noth | East | South
与 East | 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# 中标志枚举的主题。
然后你最终会发现你甚至不需要这个开关盒,如果你总是有 3 个方向而结果是缺少一个。
不,没有与您想要的相似的东西(签入单个 switch 多个对象)。
最接近的是 c# 8.0 中引入的 switch expression,但不会同时检查多个变量。
检查关于原因的最终建议,如果将枚举标记为Flags
,则确实不需要switch
语句。
不需要 switch
声明。试试这个:
EntityRoute[] all = new [] { EntityRoute.North, EntityRoute.East, EntityRoute.South, EntityRoute.West, };
EntityRoute[] array = new [] { EntityRoute.East, EntityRoute.South, EntityRoute.North, };
EntityRoute prohibitedRoute = all.Except(array).First();
Console.WriteLine(prohibitedRoute.ToString());
这给了我:
West
您甚至可以这样定义 all
:
EntityRoute[] all = Enum.GetValues(typeof(EntityRoute)).Cast<EntityRoute>().ToArray();
您可以使用 Tuple Patterns,它是 C# 8.0 的一部分
如下图
EntityRoute? prohibitedRoute = (array[0], array[1], array[2]) switch
{
(EntityRoute.North, EntityRoute.West, EntityRoute.South) => EntityRoute.East,
(EntityRoute.South, EntityRoute.West, EntityRoute.North) => EntityRoute.East,
(EntityRoute.North, EntityRoute.East, EntityRoute.South) => EntityRoute.West,
(EntityRoute.South, EntityRoute.East, 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
}
我认为这个解决方案是您实际问题的答案。
在您的具体情况下,我更喜欢 的解决方案。
我有这样的代码:
switch (array[0], array[1], array[2])
{
case (EntityRoute.North, EntityRoute.West, EntityRoute.South):
prohibitedRoute = EntityRoute.East;
return true;
case (EntityRoute.South, EntityRoute.West, EntityRoute.North):
prohibitedRoute = EntityRoute.East;
return true;
case (EntityRoute.North, EntityRoute.East, EntityRoute.South):
prohibitedRoute = EntityRoute.West;
return true;
case (EntityRoute.South, EntityRoute.East, EntityRoute.North):
prohibitedRoute = EntityRoute.West;
return true;
case (EntityRoute.South, EntityRoute.East, EntityRoute.North):
prohibitedRoute = EntityRoute.West;
return true;
}
我想做一个条件顺序不严格的系统。有没有办法在不编写额外案例的情况下做到这一点?请注意我使用的是 C# 8.0,因为我在 Unity3D 中工作。
假设这是一个 Enum
并且它被标记为 Flags
(技术上它不是必需的)你可以这样做:
[Flags]
public enum EntityRoute
{
North = 1,
East = 2,
South = 4,
West = 8
}
不过您必须确保值是唯一的,因此枚举值的顺序无关紧要,Noth | East | South
与 East | 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# 中标志枚举的主题。
然后你最终会发现你甚至不需要这个开关盒,如果你总是有 3 个方向而结果是缺少一个。
不,没有与您想要的相似的东西(签入单个 switch 多个对象)。
最接近的是 c# 8.0 中引入的 switch expression,但不会同时检查多个变量。
检查Flags
,则确实不需要switch
语句。
不需要 switch
声明。试试这个:
EntityRoute[] all = new [] { EntityRoute.North, EntityRoute.East, EntityRoute.South, EntityRoute.West, };
EntityRoute[] array = new [] { EntityRoute.East, EntityRoute.South, EntityRoute.North, };
EntityRoute prohibitedRoute = all.Except(array).First();
Console.WriteLine(prohibitedRoute.ToString());
这给了我:
West
您甚至可以这样定义 all
:
EntityRoute[] all = Enum.GetValues(typeof(EntityRoute)).Cast<EntityRoute>().ToArray();
您可以使用 Tuple Patterns,它是 C# 8.0 的一部分
如下图
EntityRoute? prohibitedRoute = (array[0], array[1], array[2]) switch
{
(EntityRoute.North, EntityRoute.West, EntityRoute.South) => EntityRoute.East,
(EntityRoute.South, EntityRoute.West, EntityRoute.North) => EntityRoute.East,
(EntityRoute.North, EntityRoute.East, EntityRoute.South) => EntityRoute.West,
(EntityRoute.South, EntityRoute.East, 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
}
我认为这个解决方案是您实际问题的答案。
在您的具体情况下,我更喜欢