在c#字典中只查找或插入一个查找

我是一名前C ++ / STL程序员,试图使用c#/ .NET技术编写快速行进算法…

我正在搜索等效的STL方法“map :: insert”,如果不存在,则在给定键处插入值,否则返回现有键值对的迭代器。

我找到的唯一方法是使用两个查找:一个在TryGetValue中,另一个在Add方法中:

List list; if (!_dictionary.TryGetValue (pcost, out list)) { list = new List (); dictionary.Add (pcost, list); } list.Add (new Point { X = nx, Y = ny }); 

是否有一些东西可以解释为什么使用.NET容器不可能? 还是我错过了一些观点?

谢谢。

您可以通过以下方式分配您的值:

 var dict = new Dictionary(); dict[2] = 11; 

如果键2的值不存在 – 它将被添加,否则它将被覆盖。

Dictionary没有方法GetOrAdd,但C#4.0的ConcurrentDictionary有:

 var dict = new ConcurrentDictionary(); dict[2] = 10; int a = dict.GetOrAdd(2, 11);// a == 10 

标准通用字典不支持此function,需要进行2次查找。 虽然查找的成本通常可以忽略不计,因此这不是问题,并且您通常可以在调整系统的其他部分时获得更好的结果,而不是尝试微量优化字典查找。

我知道支持这个.net的唯一字典是带有GetOrAdd方法的ConcurrentDictionary 。 虽然现在你正在支付同步费用。

是否有一些东西可以解释为什么使用.NET容器不可能?

在不知道真实背景的情况下,我认为这是因为词典的简单性。 只有基本的,易于理解的function: AddRemove aso,而索引操作符有一些魔力,这可能被认为是直观的。

可悲的是,bcl的实现中没有一个。 最接近的替代方法是进行两次查找,但是可以使用一种通用扩展方法来简化, 如下所示

 public static T GetOrAdd(this IDictionary dict, S key, Func valueCreator) { T value; return dict.TryGetValue(key, out value) ? value : dict[key] = valueCreator(); } 

但是有C5的实现可以开箱即用。 方法定义如下所示:

 public virtual bool FindOrAdd(K key, ref V value) { } 

我不知道他们为什么不接受Func而不是V来推迟创建对象。 C5有很多很好的类似技巧,例如,

 public virtual bool Remove(K key, out V value) public virtual bool Update(K key, V value, out V oldvalue) public virtual bool UpdateOrAdd(K key, V value, out V oldvalue) 

您可以为此创建扩展方法:

 IDictionary _dictionary = GetDictionary(); _dictionary.GetOrAdd( "asdf" ).Add( new Point(14, 15) ); // ... elsewhere ... public static class DictionaryExtensions { public static List GetOrAdd( this IDictionary> self, TKey key ) { List result; self.TryGetValue( key, out result ); if ( null == result ) { // the key value can be set to the null result = new List(); self[key] = result; } return result; } }