2

在一个 lil' c# 浏览器游戏上工作,我使用这本字典来跟踪游戏中的几个资源:

public Dictionary <String, int> resource = new Dictionary<string,int>();

其中,“黄金”随着每一次的变动而变化。

protected void timerMinute_Tick(object sender, EventArgs e)
{
resource["gold"] += (resProduction["gold"] - resConsumption["gold"])
}

现在,如果消费大于生产,这个数字就会减少。我想否认资源变成负面的。我知道我可以为每个刻度执行此操作:

if (resource["gold"] < 0)
{
resource["gold"] = 0;
}

然而,我有更多的资源要跟踪,所以虽然我可以为每个资源编写上述代码,但我只是想知道是否有人有一个聪明的方法来检查字典资源中的所有值,并将任何负数变为零。

编辑:感谢您对这里问题的所有重要建议!作为一个c#的新手,我对这一切都不是很熟悉^^

4

5 回答 5

8

您可以创建自己的字典类,以确保值是非负的。这是一个简单的示例,但您可以很容易地使其通用和可扩展。

public class ValidatedDictionary : IDictionary<string, int>
{
    private Dictionary<string, int> _dict = new Dictionary<string, int>();
    protected virtual int Validate(int value)
    {
        return Math.Max(0, value);
    }
    public void Add(string key, int value)
    {
        _dict.Add(key, Validate(value));
    }

    public bool ContainsKey(string key)
    {
        return _dict.ContainsKey(key);
    }
    // and so on: anywhere that you take in a value, pass it through Validate
于 2013-10-25T19:38:45.873 回答
1

您可以使用根本不允许负值的TValue类似,如:uint

Dictionary<string, uint>

但请注意,如果你用uint. 所以减法时一定要小心!所以也许它毕竟不是更容易使用uint,但它会保证你的值是非负的。

于 2013-10-25T21:03:13.750 回答
0

我可以想到两种方法:

for (String s in resourceNames)
  resource[s] = max(0, resProduction[s] - resConsumption[s]);

或者已经实现了一个特殊的字典类来做到这一点

于 2013-10-25T19:34:46.310 回答
0

我将封装操作并仅公开所需的操作。关键是只暴露了合同。(我通常也更喜欢使用本地化合同,这就是我不建议IDictionary直接实施的原因:它使服务非常糟糕。)

使用封装隐藏字典:

class Ticker {
   Dictionary<string, int> dict = ..;

   // I don't actually know what contract you need
   public Decay(string symbol, int value) {
      // Handle all logic uniformly here such as checking to make sure it can't
      // go negative.
   }
}

然后:

resourceStash.Decay("gold", fortKnox);

或者,使用封装来隐藏值:

也就是说,把它变成一个Dictionary<symbol, ResourceValue>(whereResourceValue又是特殊的并且封装了所需的逻辑)。

然后:

resources["gold"].LessenLoad(nuggetCount);

(或者您可以重载-运算符以使其ResourceValue行为更像整数)。

于 2013-10-25T19:35:57.973 回答
0

对您当前的设计进行一行更改怎么样?

有很多更难的方法可以做到这一点,但我能看到的最简单的方法是将您当前的方法修改为以下..

protected void timerMinute_Tick(object sender, EventArgs e)
{
    resource["gold"] = Math.Max(0, (resource["gold"] + resProduction["gold"] - resConsumption["gold"]));
}

编辑:循环遍历每种资源类型?

protected void timerMinute_Tick(object sender, EventArgs e)
{
    foreach (var resourceName in resource.Keys)
    {
        resource[resourceName] = Math.Max(0, (resource[resourceName] + resProduction[resourceName] - resConsumption[resourceName]));
    }
}
于 2013-10-25T19:43:33.077 回答