首页 > 解决方案 > 尝试查找由多个参数确定的值时如何避免大量的 if-else 检查?

问题描述

我的函数有一项工作:返回一个简单的int索引。但是,为了“计算”该索引,它考虑了一些参数(在我的例子中是 3 个,但为简单起见,我将在本例中使用 2 个参数)。我的函数看起来像这样:

int calculateIndex(int param1, int param2)

现在,它目前是如何完成这项工作的?它在“层”中这样做。首先它检查 value 是什么param1。一旦确定了这一点,它就会开始检查值是什么param2等等。像这样:

if(param1 == 0)
{
    if(param2 == 0)
    {
        // Return some value.
    }
    else if(param2 == 1)
    {

    }
    else
    {

    }
}
else if(param1 == 1)
{
    if(param2 == 3)
    {

    }
    else
    {

    }
}
else
{
    if(param2 == 4)
    {

    }
    else if(param2 == 5)
    {

    }
    else if(param2 == 6)
    {

    }
    else if(param2 == 7)
    {

    }
    else
    {

    }
}

需要注意的重要一点是,每个 case 都param1可以有任意数量的if-elsesfor param2。例如,如果param1为0,则有3种情况param2可以。但是,如果param1为 1,param2则有 2 种情况,则为3else

如果这些都没有意义,让我给你一个实际的例子。考虑以下函数:

void uselessFunction(int biome, int element)

uselessFunctionbiomeelement索引作为参数并根据输入打印适当的消息。

// Forest, Grass etc. are integer constants.

if(biome == Forest)
{
    if(element == Grass)
    {
        print("There is grass in the forest.");
    }
    else if(element == Water)
    {
        print("There is water in the forest.");
    }
    else
    {
        print("Given element is invalid for this biome.");
    }
}
else if(biome == Desert)
{
    if(element == Sand)
    {
        print("There is sand in the desert.");
    }
    else
    {
        print("Given element is invalid for this biome.");
    }
}
else
{
    print("Given biome is invalid.");
}

现在,这个例子很短,但正如你所见,只有 2 个生物群系和几个街区,这段代码已经很长了。想象一下有 20 个生物群落的情况,每个生物群落有 10-15 个方块可以出现在上面。这会导致执行一项简单任务的功能非常长,我需要一种更好的方法来设计该功能。如何?

标签: c#refactoring

解决方案


您想要的技术称为“表驱动编程”。您建立了一系列包含您感兴趣的数据的“表格”,然后您不执行 if-else 系列,而是执行表格查找。

由于您的元素表只是是-否决定,因此您甚至不需要字典;只需一组即可:

var biomeTable = new Dictionary<Biome, HashSet<Element>>()
{
  { Forest, new HashSet<Element>() { Grass, Water }},
  { Desert, new HashSet<Element>() { Sand }}
};

现在你的代码是:

if (biomeTable.ContainsKey(biome)) 
{
  if (biomeTable[biome].Contains(element))
    Console.WriteLine($"The {biome} contains {element}.");
  else
    Console.WriteLine($"The {biome} does not contain {element}.");
} 
else
   Console.WriteLine($"Invalid biome {biome}.");

看看情况如何?逻辑只是两个 if-then,没有生物群落/元素组合那么多。信息进入数据结构,而不是代码结构。

这样,您可以将生物群系和元素放入配置文件中,然后将它们从文件中解析出来,构建字典并根据需要动态设置。


推荐阅读