什么是PowerCollections中的GetValueElseAdd的BCL等价物

时间:2010-01-26 12:56:43

标签: c# .net algorithm collections hash

在Wintellect的PowerCollections中,有一个GetValueElseAdd,其工作原理如下:

if ( collection.GetValueElseAdd( key, ref value))
{
    // just added, value unmodified
}

或者

// factory method only gets called if the key is not present.
if ( collection.GetValueElseAdd( key, out value, () => thingFactory.CreateNew()))
{
    // just added; value contains factory result
}

在这两种情况下,只有一个通过散列来隔离值所在的位置。 (有关权衡的更多讨论,请参阅What happens to C# Dictionary<int, int> lookup if the key does not exist?

问题是,为什么像这样的功能没有进入BCL,特别是考虑到几乎所有其他的PowerCollections都被吸入了3.5 / LINQ并且新的集合在4.0中添加了?

是因为一般使用模式是一个只执行一次Add而你通常只用大量的时间点击一个哈希表查找TryGetValue路径的等价物吗?

是因为这在树中比在哈希表中更有价值(在网上可以only find this implementation但我认为它不仅仅是一个OrderedList集合)

编辑:另请参阅Fredrik回复评论中链接的帖子,该回复讨论了集合的Sychronized变体的多线程注意事项。

或者我还有另一个成语吗?如果只有彼得戈尔德在这里!

1 个答案:

答案 0 :(得分:2)

单一责任原则是我能提出的唯一可能与GetValueElseAdd争论的理由。方法名称表示该方法有两个职责:它尝试获取项目,如果失败,则添加项目(我从未使用过PowerCollections,但我会假设{{1}在未找到密钥的情况下,使用创建的对象分配。)

如果我正在设计API,以及行为很容易创建和封装的事实,可能足以阻止我实现它。

一旦方法名称开始包含 Else 之类的字样,我通常会尝试退后一步。这些对我来说是指示该方法可能有太多责任。