Search code examples
c#code-readability

What is the best way to implement a reordering method?


I have some code that is supposed to assign some values to its properties according to a given order.

Here is some sample code that will do the job:

public class AnimalCount
{
    public int Dogs;
    public int Cats;
    public int Fish;
    public int Birds;

    public void RankValues(string first, string second, string third, string fourth)
    {
        string property = "";
        int value = -1;
        for (int i = 0; i < 4; i++)
        {
            switch (i)
            {
                case 0: property = first;  value = 10; break;
                case 1: property = second; value = 12; break;
                case 2: property = third;  value = 19; break;
                case 3: property = fourth; value = 20; break;
            }
            switch (property)
            {
                case "dogs":  Dogs  = value; break;
                case "cats":  Cats  = value; break;
                case "fish":  Fish  = value; break;
                case "birds": Birds = value; break;
            }
        }
    }
}

There are some problems with this code, however.

  1. The main problem is how to pass the parameters. With this method, since they are passed as strings, we lose type safety. We could thus have duplicates or mismatched strings. We could use enums, but then we still have the risk of duplicates, and we would have to do some code duplication to make it work.
  2. The switches are ugly. It feels like code duplication somehow.

Is there any better solution than just filling the code with exception handling? Seems awfully ugly to me.

If you must know, I'm trying to write a function that takes a requested order of ability scores in Dungeons and Dragons and rolls for them in your selected order.


Solution

  • I would do this:

    public class AnimalCount
    {
        public int Dogs;
        public int Cats;
        public int Fish;
        public int Birds;
    
        private Dictionary<string, Action<int>> rankers
            = new Dictionary<string, Action<int>>()
        {
            { "dogs", v => Dogs = v },
            { "cats", v => Cats = v },
            { "fish", v => Fish = v },
            { "birds", v => Birds = v },
        };
    
        private Action<string, int> setRank = (t, v) =>
        {
            if (rankers.ContainsKey(t))
            {
                rankers[t](v);
            }
        };
    
        public RankValues(string first, string second, string third, string fourth)
        {
            setRank(first, 10);
            setRank(second, 12);
            setRank(third, 19);
            setRank(fourth, 20);
        }
    }