“GetOrCreate” – 这个成语是否有确定的名称?

好吧,考虑一下我们大多数人多次使用过的常见习语(我假设):

class FooBarDictionary { private Dictionary fooBars; ... FooBar GetOrCreate(String key) { FooBar fooBar; if (!fooBars.TryGetValue(key, out fooBar)) { fooBar = new FooBar(); fooBars.Add(key, fooBar); } return fooBar; } } 

它有任何确定的名称吗?

(是的,它是用C#编写的,但它可以“轻松”转移到C ++。因此该标签。)

我总是调用这样的函数obtainSomething()

这有点取决于你为什么要这样做 – 这个成语是我所见过的被称为memoization,缓存,按需初始化,首次使用时创建的成语。 通常我调用方法“ensureFoo”而不是“GetOrCreate”

我不确定高级模式的整体编程名称,但Perl有这种称为Autovivification的奇妙行为 – 即,当您查询散列中不存在的键的值时,自动创建具有未定义值的散列(映射)键。

在C#中……

…我有一个DefaultingDictionary <>来做这件事。 作为奖励

  • 您可以指定默认值或工厂函数来创建缺失键的值:
  • 它带有来自IDictionary <>的隐式转换(包装字典)
  • 它带有扩展方法,可以动态地将任何字典转换为DefaultingDictionary <>

完整代码:

扩展名.AsDefaulting可用于透明地使用任何IDictionary<>作为默认值,因此您可以选择使用任何字典(甚至例如从第三方API获得)作为默认字典,并且底层容器将使用任何字典更新’自动生活’项目。

用它就好

 IDictionary dict = LoadFromDatabase(); // using a fixed value SomeFunc(dict.AsDefaulting(defaultItem)); // using an independent generator function var defaulting = dict.AsDefaulting(() => new MyItem { Id = System.Guid.NewGuid() }); // using a keydepedent generator function var defaulting = dict.AsDefaulting(key => LazyLoadFromDatabase(key)); 

一些测试用例

被包含在内: