gpt4 book ai didi

C# 替换巨大的 if-else 语句

转载 作者:行者123 更新时间:2023-11-30 14:45:46 25 4
gpt4 key购买 nike

假设我有 Item 对象女巫主要持有这样的枚举属性

public enum Shape
{
square = 1,
trangle = 2,
any = 3
}

public enum Color
{
blue = 1,
red = 2,
yellow = 3,
green = 4
}


public enum Material
{
glass = 1,
wood = 2,
metal = 3
}


public class Item
{
public Shape ItemShape { get; set; }
public Color ItemColor { get; set; }
public Material ItemMaterial { get; set; }
}

我想做的是取决于我稍后需要做一些 Action 的全部三个属性的组合;

我正在考虑使用 if-else 组合,例如:

if(item.ItemShape == Shape.square && item.ItemColor == Color.blue && item.ItemMaterial == Material.glass)
{
//call Action1
}
else if(item.ItemShape == Shape.square && item.ItemColor == Color.blue && item.ItemMaterial == Material.wood)
{
// action2
}
......

问题是我有大约 16 种组合,所以它会是一个巨大的 if-else 方法来解决我稍后应该调用什么方法。

enter image description here

也许有任何其他方法可以替代 if-else 语句,使代码更具可读性、设计模式或更高效?

我正在考虑将所有可能的状态组合为标志枚举值,但不确定我是否可以稍后从对象属性创建枚举值。

最佳答案

我认为您最好的选择是创建一个 Dictionary,它将您的值映射到方法。
现在有几个选项可能是您字典中的关键 - 见下文。

免责声明另请注意,如果它在代码库中传播/重复并且经常更改,那么大的 if 语句只是一个问题 - 将内容放入字典并不能真正降低复杂性。在字典中包含方法也会改变代码的语义。第一个问题应该是 - 我在运行时更改映射吗?它们真的应该是动态的吗?

  1. Dictionary with key ValueTuple struct 你可以使用语法 (Shape, Color, Material) - 这是最简单的一个。 请注意 - 不是 Tuple 类,而是 ValueTuple 结构。
  2. Dictionary 与键 Item 类本身,但随后您需要在 Item注意适当的相等比较。您可以使 Item 成为一个 struct 以免费获得它(但性能较慢,这来自 System.ValueType 中的相等比较,在一般情况下使用反射),或者将其保留为类(或结构)和实现 IEquatable<Item>EqualsGetHashCode
    如果没有适当的相等比较,您的字典查找将不起作用(正如@ckuri 所建议的)
  3. 在没有字典的情况下使用 ValueTuple 来简单地压缩您的代码。
  4. State pattern 的一个变体,您的处理程序有一个共享接口(interface)/基类。 Handler 是一个单独的类,它包含针对一组特定值的一个操作,例如 AnyBlueGlassHandler : Handler 。每个处理程序检查 If 条件,如果为真,则运行操作。然后,您可以将处理程序放在 List<T> 中,并将它们应用于 handlers.Foreach(x=>x.Handle(item)) 之类的项目

Item 是 key 时,代码可能如下所示:

    public static class ItemExtensions
{
static Dictionary<Item, Action<Item>>
methods = new Dictionary<Item, Action<Item>>()
{
{ new Item(Shape.any, Color.blue, Material.glass), x=> { /*do something*/ } }
};


public static bool TryApply(this Item item)
{
if (methods.TryGetValue(item, out var action))
{
action(item);
return true;
}
return false;
}
}

ValueTuple 是 key 时的代码可能看起来像

 public static class ItemExtensionsUsingValueTuple
{
static Dictionary<(Shape, Color, Material), Action<Item>>
methods = new Dictionary<(Shape, Color, Material), Action<Item>>()
{
{ (Shape.any, Color.blue, Material.glass), x=> { /*do something*/ } }
};


public static bool TryApply(this Item item)
{
if (methods.TryGetValue((item.ItemShape, item.ItemColor, item.ItemMaterial), out var action))
{
action(item);
return true;
}
return false;
}
}

使用 ifs 的更精简版本的代码可能如下所示:

  • 在您的 Item 类上声明 Key 属性
    public (Shape, Color, Material) Key => (ItemShape, ItemColor, ItemMaterial);
  • 使用更优雅的if语句
    if ( item.Key == (Shape.any, Color.blue, Material.glass)) { }

关于C# 替换巨大的 if-else 语句,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52413018/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com