C#如何避免多个开关(委托?)

本文关键字:委托 开关 何避免 | 更新日期: 2023-09-27 18:25:28

我在代码中使用了多个开关来反映列表框中的物种选择。其中一个看起来像:

    private int getOrganelleLength() {
        int species = listBox1.SelectedIndex;
        switch (species) {
            case 0:
                //Console.WriteLine("arabidopsis");
                return 154478;
            case 1:
                //Console.WriteLine("oryza");
                return 134525;
            case 2:
                //Console.WriteLine("glycine");
                return 152218;
            default:
                Console.WriteLine("Error");
                throw new Exception("wrong speices choice");
        }
    }

第二个看起来像:

    private int getLengthOfChromosome(int number) {
        int species = listBox1.SelectedIndex;
        switch (species) {
            case 0:
                //Console.WriteLine("arabidopsis");
                return arabidopsis_chromosomes[number - 1];
            case 1:
                //Console.WriteLine("oryza");
                return oryza_chromosomes[number - 1];
            case 2:
                //Console.WriteLine("glycine");
                return glycine_chromosomes[number - 1];
            default:
                Console.WriteLine("Error");
                throw new Exception("wrong speices choice");
        }

不知何故,我觉得这不是最清晰的解决方案,这种开关的多次使用。然而,这两个函数返回的值完全不同(当然是基于物种选择)。如果有办法的话,我很想学习如何改进我的代码。非常感谢。

C#如何避免多个开关(委托?)

我假设arabidopsis_chromosomes等是数组或列表。

只需将它们添加到数组或列表中即可。

例(极其简化):

object[][] foo = {{ 1,2,3}, {4,5,6}};
object Get(int x, int y)
{
  return foo[x][y];
}

看看refacotring方法。这听起来像是用多态替换条件

因此,请为数据对象使用类。

您可以编写:

private int getOrganelleLength() {
    var dict = new Dictionary<int, int>() { {0, 154478}, {1, 134525}, {2, 152218} };
    return dict[listBox1.SelectedIndex];
}
private int getLengthOfChromosome(int number) {
    var dict = new Dictionary<int, Func<int>>() {
           {0, () => arabidopsis_chromosomes[number - 1]},
           {1, () => oryza_chromosomes[number - 1]}
           {2, () => glycine_chromosomes[number - 1]}}; 
    return dict[listBox1.SelectedIndex]();
 }

在最后一种情况下,您实际上不需要Func,因为您只需在字典值中添加arabidopsis_chromosomes,就可以写更多的例子。

无论如何,只有当你有一个非常非常简单的开关时,它才会起作用如果你需要一些更难写的东西,不要用在这种情况下,您应该重构代码并使用多态性和工厂。

首先,应该在default的情况下抛出NotImplementedException,而不是Exception

然后,您应该查看Func<T, TResult>代表。

你可以让你的代码看起来像

private int GetInformationAboutSpecies(ListBox listBox, ISwitchCaseResolver helper)
{
    return helper.GetInformation(listBox.SelectedIndex);
}

然后,您可以为每个物种实现ISwitchCaseResolver接口的具体类。您还可以考虑使用Factory模式来调用接口的正确implementation。