用字典计数而不永久检查是否存在?

Count things with a dictonary without permanently check for existance?

今天我用这样的代码来计数:

Dictionary<string,int> wordCount = new Dictionary<string,int>();
if (!wordCount.ContainsKey(word))
{
    wordCount.Add(word, 0);
}
wordCount[word]++;

有没有更优雅的方法来计算事物而不永久检查是否存在?

我想做这样的事情:

Dictionary<string,int> wordCount = new Dictionary<string,int>();
wordCount[word]++;

并且新键的值应自动初始化为默认值(例如 0 表示 int)。

有没有一种优雅的方式来实现这个?

提前致谢。

您可以像这样为字典定义扩展方法:

public static class DictionaryExtension
{
    public static void AddCount<T>(this Dictionary<T, int> dict, T key)
    {
        if (dict.ContainsKey(key))
        {
            dict[key]++;
        }
        else
        {
            dict[key] = 1;
        }
    }
}

然后你可以像这样使用它:

Dictionary<string, int> count = new Dictionary<string, int>();
count.AddCount("foo");
count.AddCount("bar");
count.AddCount("foo");

要更进一步,您可以从 Dictionary 派生新类型并引入新索引器:

public class FancyDict<T> : Dictionary<T,int>
{
    public new int this[T key]
    {
        get => this.ContainsKey(key) ? base[key] : 0;
        set => base[key] = value;
    }
}

这使得使用 [] 语法成为可能:

FancyDict<string> fancyCount = new FancyDict<string>();
fancyCount["foo"]++;
fancyCount["bar"]++;
fancyCount["foo"]++;

foreach (var key in fancyCount.Keys)
{
    Console.WriteLine(key + " : " + fancyCount[key]);
}

如果键不存在,TryGetValue() 方法会将 out 参数设置为其默认值。您可以利用它来简化代码,如下所示:

wordCount.TryGetValue(word, out int count);
wordCount[word] = count + 1;

这就像您将要获得的一样简单,当您不知道要使用什么键时,除非通过数据迭代(显然,如果您知道键,您可以在开始计数之前用所有键初始化字典)。

当然,您始终可以将任何常用代码封装在扩展方法或其他抽象中,以进一步简化调用站点本身。以上解释了如何简化实现.