使用 2 个不同的枚举生成唯一值以充当 switch 语句中的情况

问题描述 投票:0回答:1

我正在尝试制作一个具有多种碰撞体类型(即 AABB 和圆形)的碰撞系统。每种类型的碰撞器都需要运行一种独特的碰撞检查方法。为了确定类型,我给每个碰撞器一个枚举来说明其类型。然后,当程序检查碰撞时,它可以比较它们的类型并运行相应的方法来检查该类型的碰撞。

我可以使用 if else-if 垃圾邮件来做到这一点,就像这样

if (colliderA.ColliderType == ColliderType.Circle && colliderB.ColliderType == ColliderType.Circle)
{
    // Check circle-circle collision
}
else if (colliderA.ColliderType == ColliderType.Circle && colliderB.ColliderType == ColliderType.Box)
{
    // Check circle-box collision
}
else if (...)
{
    // And so on
}

但是这很糟糕,有多个明显的原因,最明显的是它只检查 a 是 x 和 b 是 y,而不检查具有相同结果的其他情况(a 是 y 和 b 是 x)。

无论如何,使用带有枚举的 switch 语句更有意义,但这会导致另一个问题,即获取代表 2 个不同枚举状态的唯一数字。我想出了一个可行的解决方案,但有一些我不喜欢的奇怪问题。我的方法是将每个枚举转换为其数字表示形式,然后对第二个枚举进行位移位以创建唯一的数字。

int enumValue = ((int)colliderA.ColliderType << 8) + (int)colliderB.ColliderType;
这个解决方案有两个问题困扰着我。首先是这样阅读代码是多么困难

switch (enumValue) { case 1: case 256: // Both of these cases are for circle-box collisions // They are both far apart from each other and difficult to tell what they mean at a glance break; }
我可以这样做,但读起来也有点奇怪

case ((int)ColliderType.Circle << 8) + (int)ColliderType.Box: case ((int)ColliderType.Box << 8) + (int)ColliderType.Circle:
这感觉像是在 C#(我正在使用的)等语言中内置了一个简单的解决方案,就像枚举标志之类的东西一样,但即使不是,我觉得仍然必须有一种通用的方法来完成我的任务我以高效且可读的方式寻找。有人可以给我一些指点吗?

TLDR:给定两个枚举,是否可以生成一个唯一的数字来表示它们的状态(其中输入 (A, B) 和 (B, A) 给出相同的输出)

c# enums switch-statement
1个回答
0
投票
您可以使枚举常量具有 2 的幂作为其值,并使用按位或将它们组合成单个枚举值。

示例:

// You can optionally add the [Flags] attribute to this enum CollisionType { A = 1, B = 2, C = 4, D = 8 // and so on } ... CollisionType combinedType = collider1.Type | collider2.Type; switch (combinedType) { case CollisionType.A | CollisionType.B: // this is the same value as CollisionType.B | CollisionType.A ... break; case CollisionType.A | CollisionType.A: // or just CollisionType.A, depending on what you find more readable ... break; // and so on }
或者,如果您无法修改枚举,您可以创建一个元组来表示一对碰撞类型:

var combinedType = (collider1.Type, collider2.Type); switch (combinedType) { case (CollisionType.A, CollisionType.B): case (CollisionType.B, CollisionType.A): ... break; // and so on }
    
© www.soinside.com 2019 - 2024. All rights reserved.