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

本文关键字:设置 字典 | 更新日期: 2023-09-27 18:37:03

在开发一个 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;
}

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

编辑:感谢对这里问题的所有好建议!作为 c# 的新手,我对它不太熟悉^^

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

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

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
您可以使用

uint这样的TValue,它根本不允许负值,如下所示:

Dictionary<string, uint>

但请注意,如果您用uint从小事物中减去大的东西,您的减法将"环绕"。所以减法时要小心!因此,也许毕竟使用uint并不容易,但它可以保证您的值是非负的。

我会封装操作并仅公开所需的操作。关键是只有合同被曝光。(我通常也更喜欢使用本地化的合同,这就是为什么我不建议直接实施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的行为更像整数)。

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

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

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

我可以想到两种方法:

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

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