当我想添加新项目时如何使用词典?

时间:2017-01-22 19:09:42

标签: c# .net dictionary

当我使用散列集时,我可以尝试添加新项目,如果该项目存在则无论如何都不会。 hashset不会抛出异常而只是继续。

使用词典,如果我想添加一个新项目,如果该键存在,则抛出异常。目前我总是那样做:

Dictionary<long, List<string>> myDic = new Dictionary<long, List<string>>();
long myNewKey = 1;
if(myDic.ConatainsKey(1) == false)
{
    myDic.Add(1, new List<string>());
}
myDic[myNewKey].Add("string01");
myDic[myNewKey].Add("string02");

当我想向dictonary添加新值时,它会让我随时重复许多代码。 这让我想知道是否有更好的方法来使用字典。

我也在想我可以创建一个扩展方法,但我想知道是否有更好的选择。

3 个答案:

答案 0 :(得分:2)

取决于字典值的类型(如键值)。在您的示例中,长键指向字符串列表,真正的问题是需要创建新的对象值。如果Dictionary是指向值类型(例如:long-&gt; long)的值类型(如值与引用类型),则可以使用索引器&#39; [x]&#39;。如果您知道键的范围,则可以提前初始化值对象。如果您只是想减少代码,可以使用扩展方法来组合检查,添加对象和集合。像这样:

public static class Extensions {
    public static void AppendToValues(this Dictionary<long, List<string>> dict, long key, string str){
        if (dict.ContainsKey(key)) {
            dict.Add(key, new List<string>());
            }
        dict[key].Add(str);
        }
    }   

然后在你的代码中调用它:

myDic.AppendToValues(myNewKey, "string01");

答案 1 :(得分:1)

Dictionary<TKey,TValue>有两种不同的方式来添加项目。

void Add(TKey key, TValue value):因为你正在调用Add你所说的语义是“这不存在,让它存在”。因此,重复插入会引发异常,因为它不知道您是想要旧的还是新的东西。

索引器(TValue this[TKey key])支持赋值,其语义为“如果我调用索引器getter,我希望这是答案”。

dict.Add(1, 1);
var x = dict[1]; // x == 1
dict.Add(1, 2); // throws

dict.Add(1, 1);
var x = dict[1]; // x == 1;
dict[1] = 2;
var y = dict[1]; // x == 1, y == 2.

var dict = new Dictionary<long, int>();
dict[1] = 35;
var x = dict[1]; // x == 35;

ContainsKey几乎总是错误的召唤。如果您正在安全地阅读该值,请致电TryGetValue,如果您只想使用字典存储某些内容,请使用HashSet<T>。 (Add方法返回booltrue如果添加添加内容(不存在),false如果添加无效(值已存在)) )。

在您想要将内容添加到列表的特定情况下,TryGetValue方法是最好的。或者,使用ConcurrentDictionary:

TryGetValue:

List<string> list;

// Read the dictionary exactly once
if (!dict.TryGetValue(key, out list))
{
    list = new List<string>();
    // Write at most once.
    dict[key] = list;
}

list.Add(value);

ConcurrentDictionary:

ConcurrentDictionary<long, List<string>> dict = new ConcurrentDictionary<long, List<string>>();
...
List<string> list = dict.GetOrAdd(key, () => new List<string>());
list.Add(value);

答案 2 :(得分:0)

我认为如果没有扩展方法(或者是一个字典子类,顺便说一句就是矫枉过正的话),你可以达到你想要的效果。

你可以在这里找到一个很好的扩展方法实现,利用Dictionary.TryGetValue(如果没有找到键就不会抛出异常):

Dictionary returning a default value if the key does not exist

如果您仍然不想使用扩展方法,TryGetValue将提供更好的性能,因为密钥的查找只进行一次:

Dictionary<long, List<string>> myDic = new Dictionary<long, List<string>>();
long myNewKey = 1;
List<string> list;
if (!myDic.TryGetValue(myNewKey, out list))
{
    list = new List<string>();
    myDic.Add(myNewKey, list);
}

list.Add("string01");
list.Add("string02");