实施重新排序方法的最佳方法是什么?

时间:2014-01-07 08:01:56

标签: c# code-readability

我有一些代码应该根据给定的顺序为其属性分配一些值。

以下是一些可以完成工作的示例代码:

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

但是,此代码存在一些问题。

  1. 主要问题是如何传递参数。使用这种方法,由于它们作为字符串传递,我们失去了类型安全性。因此,我们可能有重复或不匹配的字符串。我们可以使用枚举,但是我们仍然有重复的风险,我们必须做一些代码重复才能使它工作。
  2. 开关很难看。感觉就像代码重复一样。
  3. 有没有比只用异常处理填充代码更好的解决方案?对我来说似乎太难看了。

    如果你必须知道,我正在尝试编写一个函数,该函数在“龙与地下城”中获取所需的能力分数顺序,并按所选顺序为它们滚动。

4 个答案:

答案 0 :(得分:2)

我会这样做:

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

答案 1 :(得分:1)

不完全确定我是否关注你,但你能不能简单地收集4个参数的有序集合?

public void doWhatever(String[] orderedParams) {
    this.animals = orderedParams;
    // ... 
    this.doTheThing(animals[0], 10);
    this.doTheThing(animals[1], 12);
    // etc
}

答案 2 :(得分:1)

字典对于结果来说是一个很好的容器,因为你基本上想要一个键/值对。如果您将两个集合提供给排名函数

public Dictionary<string, int> Rank(string[] orderedKeys, int[] orderedValues)
{
    Dictionary<string, int> rankedDictionary = new Dictionary<string, int>();
    for (int i = 0; i < orderedKeys.Length; i++)
    {
        rankedDictionary.Add(orderedKeys[i], orderedValues[i]);
    }
    return rankedDictionary;
}

public void CallRank()
{
    string[] orderedKeys = new[] { "dogs", "cats", "fish", "birds" };
    int[] orderedValues = new[] { 10, 12, 19, 20 };

    Dictionary<string,int> rankedResults =  Rank(orderedKeys, orderedValues);

    int catsValue = rankedResults["cats"];
}

我问你是否使用C#的原因是因为如果你担心强类型变量,而不是使用“cat”和“dog”等字符串。你可以在c#中使用枚举。

http://msdn.microsoft.com/en-us/library/sbbt4032.aspx

public enum Animals
{
    Dog
    Cat
    ....
}

所以你的字典是

类型
Dictionary<Animals, int>

你可以这样访问它

int dogValue = rankedDictionary[Animals.Dog];

答案 3 :(得分:0)

从其他答案中获取想法,我认为实现这一点的最佳方法如下:

using System.Collections.Generic;
public class AnimalCount
{
    public int Dogs { get { return animals["dogs"]; } }
    public int Cats { get { return animals["cats"]; } }
    public int Fish { get { return animals["fish"]; } }
    public int Birds { get { return animals["birds"]; } }

    private Dictionary<string, int> animals = new Dictionary<string, int>();

    public void RankValues(string first, string second, string third, string fourth)
    {
        animals[first] = 10;
        animals[second] = 12;
        animals[third] = 19;
        animals[fourth] = 20;
    }
}

并使用类型安全的枚举:

using System.Collections.Generic;

public enum Animals
{
    Dogs, Cats, Fish, Birds
}

public class AnimalCount
{
    public int Dogs { get { return animals[Animals.Dogs]; } }
    public int Cats { get { return animals[Animals.Cats]; } }
    public int Fish { get { return animals[Animals.Fish]; } }
    public int Birds { get { return animals[Animals.Birds]; } }

    private Dictionary<Animals, int> animals = new Dictionary<Animals, int>();

    public void RankValues(Animals first, Animals second, Animals third, Animals fourth)
    {
        animals[first] = 10;
        animals[second] = 12;
        animals[third] = 19;
        animals[fourth] = 20;
    }
}