获取两个变量及其顺序的函数无关紧要

时间:2017-06-12 10:18:23

标签: c# function variables

很抱歉,我无法在问题标题中更好地解释。我会在这里更好地定义我的问题。

这就是我正在做的事情 - 在我的游戏中,可以选择彼此使用物品。对于每对项目,游戏执行动作。

目前,游戏使用了两个变量:“ItemUsed”和“ItemUsedOn”。首先,游戏选择第一项 - 其id转到“ItemUsed”,然后他选择第二项,它的id转到“ItemUsedOn”。然后,存在一个定义特定操作的空白。

代码的简短示例:

if (ItemUsed == "itm_cable")
{
    if (ItemUsedOn == "itm_towel")
        SubMain.ItemsMergedText = "To achieve what?";
    else if (ItemUsedOn == "itm_wet_towel")
        SubMain.ItemsMergedText = "No, water will damage it";
    else if (ItemUsedOn == "itm_glass")
        SubMain.ItemsMergedText = "I don't need to cut the cable";
}

if (ItemUsed == "itm_book_electronics")
{
    if (ItemUsedOn == "itm_towel")
        SubMain.ItemsMergedText = "Why?";
    if (ItemUsedOn == "itm_wet_towel")
        SubMain.ItemsMergedText = "No, water will damage the book";
    else if (ItemUsedOn == "itm_soap")
        SubMain.ItemsMergedText = "Wrong plan";
    else if (ItemUsedOn == "itm_hair")
        SubMain.ItemsMergedText = "It won't help";
}

还有很多这样的配对。 但是,这种方法存在问题。当两个项目组合时,它们的顺序无关紧要,例如“itm_toolbox”可以是“ItemUsed”而“itm_cable”可以是“ItemUsedOn”,但也可以是相反的方式,结果将是相同的。如何实现这一目标?

如果符合以下条件,我确实尝试在每个“较大”中使用它:

else
    CombineItems(ItemUsedOn, "itm_book_edda");

但这并不总是有效,我找不到原因。

所以,我正在寻找的是获得2个变量的函数:

void CombineItems(string Item1, string Item2)

然后在这些情况下给出相同的结果:

if (Item1="Tomato")&&(Item2="Cucumber")
    Item3="Salad"

if (Item1="Cucumber")&&(Item2="Tomato")
    Item3="Salad"

我的问题:如果不使用这么多“if's”,有没有更简单的方法呢?

提前谢谢你, 叶甫盖尼

5 个答案:

答案 0 :(得分:5)

我建议你创建一个例如UnorderedPair类型,它会覆盖.Equals和/或==的行为,这样:

new UnorderedPair("Tomato", "Cumcumber") == new UnorderedPair("Cucumber", "Tomato");

然后,您可以将所有if语句缩减为简单字典:

combinedItems = new Dictionary<UnderedPair, string>
{
    [new UnorderedPair("Tomato", "Cumcumber")] = "Salad",
    [new UnorderedPair("Bread", "Filling")] = "Sandwich",
    ...
};

然后您的确定文本的代码可以是:

SubMain.ItemsMergedText = combinedItems[new UnorderedPair(ItemUsed, ItemUsedOn)];

答案 1 :(得分:2)

您可以使用params(将它们视为数组)和LINQ。将沙拉项目也存放在一个阵列中:

private string[] SaladItems = new string[] { "Tomato", "Cucumber" };

string CombineItems(params string[] Items)
{
    bool isSalad = SaladItems.Length == Items.Length && !SaladItems.Except(Items).Any();
    if (isSalad) return "Salad";
    // other types ...

    return null; // no match, exception?
}

侧注:如果你想接受“番茄”(所以忽略这种情况)请使用:

!SaladItems.Except(Items, StringComparer.InvariantCultureIgnoreCase).Any()

答案 2 :(得分:1)

如果将逻辑结构化为单独的部分,则可以使这个无穷无尽的比较列表变得更小。

首先,我会创建一个列表左右来保存项目及其结果:

var items = new[] { new { Item1 = "tomato", Item2 = "Cucumber", Result = "Salad" }
                  , new { Item1 = "tomato2", Item2 = "Cucumber2", Result = "Salad2" }
                  };

然后找到匹配的项目:

var match = items.FirstOrDefault
                (itm => (itm.Item1 == Item1 && itm.Item2 == Item2)
                        || (itm.Item1 == Item2 && itm.Item2 == Item1)
                );

答案 3 :(得分:1)

有两种方法可以降低整个代码中的重复数量:

  • 对项目进行排序,使其按字母顺序排列:

    if(Item1 > Item2) {
      var tmp = Item2;
      Item2 = Item1;
      Item1 = tmp;
    }
    

    现在,您剩下的所有代码都可以假设Item1值的字母顺序始终早于Item2,因此您只需编写:

     if (Item1="Cucumber")&&(Item2="Tomato")
         Item3="Salad"
    
  • 或者,您可以在耗尽所有选项后(再次只写一次),使用交换的参数递归调用您的方法:

    void TakeAction(Item1, Item2) {
         .
         .
         .
         /* No matches */
         else {
             TakeAction(Item2,Item1);
         }
    }
    

答案 4 :(得分:0)

var items= new HashSet<string>();
items.Add("tomato");
items.Add("Cucumber");

if(items.Contains("tomato") && items.Contains("Cucumber")) //Order does **NOT** matter
     Item3="Salad";