C#如何避免多个交换机(委托?)

时间:2012-02-23 09:38:18

标签: c# delegates switch-statement

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

    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");
        }

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

4 个答案:

答案 0 :(得分:1)

我认为arabidopsis_chromosomes等是数组或列表。

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

例如(非常简化):

object[][] foo = {{ 1,2,3}, {4,5,6}};

object Get(int x, int y)
{
  return foo[x][y];
}

答案 1 :(得分:1)

看看refacotring方法。这听起来像Replace Conditional with Polymorphism

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

答案 2 :(得分:1)

你可以写:

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,写了更多的例子。

无论如何,只有你有非常简单的开关才能工作。 如果你需要更难写的东西,不要使用它。对于这种情况,你应该重构你的代码并使用多态和工厂。

答案 3 :(得分:1)

首先,您应该在NotImplementedException案例中抛出default而不是Exception

然后,你应该看看Func<T, TResult> delegate

您可以让代码看起来像

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

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