如何优化墙体类型判断中的多else if分支代码?
墙体类型判断代码优化方案
问题场景
我有一段代码可根据特定规则生成与墙体关联的二进制数,需通过该二进制数判断墙体类型,示例如下:
public static readonly HashSet<byte> WallDiagonalCornerUpRight = new() { 0b00000100, 0b00000101 };
现有代码功能正常且性能良好,但TileBase方法的冗长else if链导致代码外观不佳,现有代码如下:
internal void SetSingleCornerWall(Vector2Int position, string binaryType) { var typeAsByte = Convert.ToByte(binaryType, 2); TileBase tile = TileBase(typeAsByte, null); if (tile != null) SetSingleTile(wallTilemap, tile, position); } // 需要优化的方法 private TileBase TileBase(byte typeAsByte, TileBase tile) { if (WallHashType.WallInnerCornerDownLeft.Contains(typeAsByte)) tile = wallInnerCornerDownLeft; else if (WallHashType.WallInnerCornerDownRight.Contains(typeAsByte)) tile = wallInnerCornerDownRight; else if (WallHashType.WallDiagonalCornerDownLeft.Contains(typeAsByte)) tile = wallDiagonalCornerDownLeft; else if (WallHashType.WallDiagonalCornerDownRight.Contains(typeAsByte)) tile = wallDiagonalCornerDownRight; else if (WallHashType.WallDiagonalCornerUpRight.Contains(typeAsByte)) tile = wallDiagonalCornerUpRight; else if (WallHashType.WallDiagonalCornerUpLeft.Contains(typeAsByte)) tile = wallDiagonalCornerUpLeft; else if (WallHashType.WallFullEightDirections.Contains(typeAsByte)) tile = wallFull; else if (WallHashType.WallBottomEightDirections.Contains(typeAsByte)) tile = wallBottom; return tile; }
请问这种情况下最佳的代码优化方案是什么?
优化方案
方案1:使用字典映射**(推荐)**
核心思路是提前构建二进制值集合到Tile的映射关系,将判断逻辑转换为字典查找,代码更简洁且易维护,新增墙体类型时只需在字典中添加条目即可。
实现步骤:
- 若追求极致查找性能,可将所有HashSet中的二进制值平铺为
byte到TileBase的直接映射:
private readonly Dictionary<byte, TileBase> _wallByteMap; // 在类构造函数中初始化映射 public YourClassName() { _wallByteMap = new Dictionary<byte, TileBase>(); // 批量添加每个墙体类型的二进制值映射 AddWallBytesToMap(WallHashType.WallInnerCornerDownLeft, wallInnerCornerDownLeft); AddWallBytesToMap(WallHashType.WallInnerCornerDownRight, wallInnerCornerDownRight); AddWallBytesToMap(WallHashType.WallDiagonalCornerDownLeft, wallDiagonalCornerDownLeft); AddWallBytesToMap(WallHashType.WallDiagonalCornerDownRight, wallDiagonalCornerDownRight); AddWallBytesToMap(WallHashType.WallDiagonalCornerUpRight, wallDiagonalCornerUpRight); AddWallBytesToMap(WallHashType.WallDiagonalCornerUpLeft, wallDiagonalCornerUpLeft); AddWallBytesToMap(WallHashType.WallFullEightDirections, wallFull); AddWallBytesToMap(WallHashType.WallBottomEightDirections, wallBottom); } // 辅助方法:将单个墙体类型的所有二进制值加入字典 private void AddWallBytesToMap(HashSet<byte> byteSet, TileBase tile) { foreach (byte b in byteSet) { _wallByteMap[b] = tile; } }
- 简化后的
TileBase方法(O(1)时间复杂度查找):
private TileBase TileBase(byte typeAsByte, TileBase tile) { return _wallByteMap.TryGetValue(typeAsByte, out var matchedTile) ? matchedTile : tile; }
如果希望初始化更直观,也可以用HashSet<byte>作为字典键(查找时遍历字典判断集合包含关系),但性能略低于平铺byte的版本:
private readonly Dictionary<HashSet<byte>, TileBase> _wallTypeMap; public YourClassName() { _wallTypeMap = new Dictionary<HashSet<byte>, TileBase> { { WallHashType.WallInnerCornerDownLeft, wallInnerCornerDownLeft }, { WallHashType.WallInnerCornerDownRight, wallInnerCornerDownRight }, { WallHashType.WallDiagonalCornerDownLeft, wallDiagonalCornerDownLeft }, { WallHashType.WallDiagonalCornerDownRight, wallDiagonalCornerDownRight }, { WallHashType.WallDiagonalCornerUpRight, wallDiagonalCornerUpRight }, { WallHashType.WallDiagonalCornerUpLeft, wallDiagonalCornerUpLeft }, { WallHashType.WallFullEightDirections, wallFull }, { WallHashType.WallBottomEightDirections, wallBottom } }; } private TileBase TileBase(byte typeAsByte, TileBase tile) { foreach (var kvp in _wallTypeMap) { if (kvp.Key.Contains(typeAsByte)) { return kvp.Value; } } return tile; }
方案2:使用switch表达式(C# 8.0+)
如果不想引入额外字典字段,可用switch表达式简化冗长的else if链,代码更紧凑:
private TileBase TileBase(byte typeAsByte, TileBase tile) { return typeAsByte switch { _ when WallHashType.WallInnerCornerDownLeft.Contains(typeAsByte) => wallInnerCornerDownLeft, _ when WallHashType.WallInnerCornerDownRight.Contains(typeAsByte) => wallInnerCornerDownRight, _ when WallHashType.WallDiagonalCornerDownLeft.Contains(typeAsByte) => wallDiagonalCornerDownLeft, _ when WallHashType.WallDiagonalCornerDownRight.Contains(typeAsByte) => wallDiagonalCornerDownRight, _ when WallHashType.WallDiagonalCornerUpRight.Contains(typeAsByte) => wallDiagonalCornerUpRight, _ when WallHashType.WallDiagonalCornerUpLeft.Contains(typeAsByte) => wallDiagonalCornerUpLeft, _ when WallHashType.WallFullEightDirections.Contains(typeAsByte) => wallFull, _ when WallHashType.WallBottomEightDirections.Contains(typeAsByte) => wallBottom, _ => tile }; }
方案对比
- 平铺byte的字典映射:性能最优(O(1)查找),可维护性最高,新增墙体类型只需添加映射,适合频繁调用的场景。
- HashSet键的字典映射:初始化直观,但查找时需遍历字典,性能略低,适合集合不频繁变动的场景。
- switch表达式:无需额外字段,代码简洁,但新增类型仍需修改方法内的表达式,维护性不如字典方案。
内容的提问来源于stack exchange,提问作者A_sind
相关产品推荐
相关产品推荐

