[英]Can anyone explain why Dictionary<> in C# doesn't work like map<T,U> in STL?
When I first started to program in C# last year, I immediately looked for the equivalent to STL's map, and learned about Dictionary. 去年我第一次开始使用C#进行编程时,我立即寻找了与STL相同的地图,并学习了Dictionary。
UPDATE crossed out this garbage below, I was completely wrong. 更新了下面的垃圾,我完全错了。 My experience with STL's map was that I hated when I requested it for a value, and if the key wasn't in the map, it would automatically create the value type (whatever its default constructor did) and add it to the map.
我对STL地图的体验是,当我向它请求一个值时,我讨厌它,如果键不在地图中,它会自动创建值类型(无论其默认构造函数如何)并将其添加到地图中。 I would have to then check for this condition in code and throw an exception.
然后我必须在代码中检查这个条件并抛出异常。
Dictionary<> gets the whole shebang correct -- if the key isn't there, it throws the exception if you're requesting the value, or automatically adds it if it's not and you want to set the value. 字典<>使整个shebang正确 - 如果键不存在,它会在您请求值时抛出异常,或者如果不是,则自动添加它并且您想要设置该值。
But you all already knew that. 但你们都已经知道了。 I should have written my unit tests before posting here and embarrassing myself.
我应该在发布之前编写我的单元测试并让自己感到尴尬。 :) They're written now!
:)他们现在写的!
Now I love Dictionary and all, but the thing that bugs me the most about it right now is that if the key isn't in the Dictionary, it throws a KeyNotFoundException. 现在我喜欢Dictionary和all,但是现在最让我烦恼的是,如果键不在Dictionary中,它会抛出KeyNotFoundException。 Therefore, I always need to write code like this: 因此,我总是需要编写如下代码:
Dictionary<string,string> _mydic; public string this[string key] { get { return _mydic[key]; // could throw KeyNotFoundException } set { if( _mydic.ContainsKey( key)) _mydic[key] = value; else _mydic.Add( key, value); } }
Why doesn't Dictionary automatically add the key value pair if the key doesn't exist, like STL's map? 如果键不存在,为什么Dictionary不会自动添加键值对,如STL的映射?
Now the funny thing is that in a previous life, I used to get annoyed because I'd often have to try to prevent map from doing just that. 现在有趣的是,在以前的生活中,我曾经生气,因为我经常不得不试图阻止地图这样做。 I guess my use cases right now are a little different. 我想我现在的用例有点不同。
Which value would you want it to return if it didn't exist in the map already? 如果地图中不存在,您希望它返回哪个值? It could return
default(TValue)
- but then it would be somewhat easy to accidentally use a value assuming it was correct. 它可以返回
default(TValue)
- 但是假设它是正确的,那么意外地使用值会有些容易。 Note that if you want that behaviour, you can use: 请注意,如果您需要该行为,可以使用:
get {
string value;
if (!_mydic.TryGetValue(key, out value))
value = default(string);
return value;
}
I wouldn't personally recommend it in general, but if you're happy not to be able to distinguish (via this indexer) between a key with a null value and a missing key, it will do the trick. 我不会亲自推荐它,但是如果你很高兴不能区分(通过这个索引器)一个具有空值和缺失键的键,那么它就可以解决问题。
Note that your setter can me a lot simpler - just 请注意,你的二传手可以让我更简单 - 只是
_mydic[key] = value;
will overwrite if necessary. 必要时会覆盖。
I agree handling the exception is kind of annoying, especially for reference types when getting a null usually makes sense. 我同意处理异常有点烦人,特别是对于引用类型,获取null通常是有道理的。 In either case though you can use
Dictionary<>.TryGetValue()
to get the value in one call. 在任何一种情况下,您都可以使用
Dictionary<>.TryGetValue()
来获取一次调用中的值。
I'm confused. 我糊涂了。 It does, here.
它确实在这里。 The docs even say so:
文档甚至这样说:
When you set the property value, if the key is in the Dictionary(TKey, TValue), the value associated with that key is replaced by the assigned value. If the key is not in the Dictionary(TKey, TValue), the key and value are added to the dictionary.
and 和
KeyNotFoundException: The property is retrieved and key does not exist in the collection.
(no mention of it being thrown during assignment). (没有提到它在任务期间被抛出)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.