Perlnika
Perlnika

Reputation: 5066

C# how to avoid multiple switches (delegate?)

I am using multiple switches in my code to reflect species choice in listbox. One of them looks like:

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

second looks like:

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

I somehow feel that this is not the clearest solution, this multiple use of switch. However, both functions return completely different values (based on species choice, of course). I would love to learn how to improve my code, if there is a way to. Thanks a lot.

Upvotes: 2

Views: 1531

Answers (4)

Guillaume
Guillaume

Reputation: 1802

First, you should throw a NotImplementedException in your default case and not an Exception.

Then, you should take a look at Func<T, TResult> delegate.

You could have your code looking something like

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

You can then implement a concrete class of ISwitchCaseResolver interface for each of your species. You may also consider using a Factory pattern to call the correct implemtantion of your interface.

Upvotes: 1

Archeg
Archeg

Reputation: 8462

You could write:

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]();
 }

In the last case you don't need actually Func, as you can just add to dictionary values arabidopsis_chromosomes, wrote that more for an example.

Anyway that will work only if you have very very simple switch. If you need some more difficult stuff to write, do not use that. For that case you should refactor your code and use polymorphism and factories.

Upvotes: 1

Tarion
Tarion

Reputation: 17164

Take a look on refacotring methods. This sounds like Replace Conditional with Polymorphism

So use classes for your data objects.

Upvotes: 1

leppie
leppie

Reputation: 117300

I assume arabidopsis_chromosomes et al, are arrays or lists.

Just add them to an array or list.

Eg (extremely simplified):

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

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

Upvotes: 1

Related Questions