如何将字典中的所有负值设置为零?

时间:2013-10-25 19:30:39

标签: c# dictionary

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

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

Amoungst那些,“黄金”,每个滴答都会改变。

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

现在,如果消费量大于产量,则数量会减少。我想否认资源变得消极。我知道我可以为每个刻度执行此操作:

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

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

编辑:感谢您对此问题的所有好建议!作为c#的新手,我对它并不是很熟悉^^

5 个答案:

答案 0 :(得分: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

答案 1 :(得分:1)

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

Dictionary<string, uint>

但是请注意,如果你用uint从较小的东西中减去一些大的东西,那么你的减法会“环绕”。所以当你减去时你应该小心!所以也许毕竟使用uint并不容易,但它会保证你的价值是非负的。

答案 2 :(得分:0)

我可以想到两种方式:

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

或实现了一个执行此操作的特殊字典类

答案 3 :(得分: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>(其中ResourceValue再次特殊并封装所需的逻辑)。

然后:

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

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

答案 4 :(得分: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]));
    }
}