18

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

class FooBarDictionary
{
    private Dictionary<String, FooBar> fooBars;

    ...

    FooBar GetOrCreate(String key)
    {
        FooBar fooBar;

        if (!fooBars.TryGetValue(key, out fooBar))
        {
            fooBar = new FooBar();
            fooBars.Add(key, fooBar);
        }

        return fooBar;
    }
}

它有什么既定的名称吗?

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

4

5 回答 5

9

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

于 2009-09-22T20:23:53.680 回答
9

这有点取决于你为什么这样做——我见过的习惯用法被称为记忆化、缓存、按需初始化、首次使用时创建。通常我将方法称为“ensureFoo”而不是“GetOrCreate”

于 2009-09-22T20:25:18.980 回答
5

延迟加载

http://en.wikipedia.org/wiki/Lazy_loading

于 2009-09-22T20:20:56.790 回答
1

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

于 2009-09-22T20:40:30.790 回答
0

在 C#...

...我有一个 DefaultingDictionary<> 可以解决这个问题。作为奖励

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

完整代码:

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

像这样使用它

IDictionary<string, MyItem> 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));

一些测试用例

被包含在内:

于 2012-05-25T19:10:30.853 回答