【问题标题】:"GetOrCreate" - does that idiom have an established name?“GetOrCreate”——这个成语有固定的名字吗?
【发布时间】:2010-11-30 13:05:47
【问题描述】:

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

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++。因此有那个标签。)

【问题讨论】:

  • 我总是这样称呼它:GetOrCreate。
  • 做 C++,我似乎总是不得不使用std::map&lt;T&gt;::find(),因为愚蠢的std::map&lt;T&gt;::operator[]() 添加了缺失值,我只想找到那些已经存在的值。使用 C#,我似乎总是需要“获取或创建”并且必须编写以上内容,因为没有像漂亮的 std::map&lt;T&gt;::operator[]() 这样简单的操作可用。这不奇怪吗?
  • @sbi:std::map&lt;T&gt;::operator[]() 不仅添加了缺失值,它还替换了已经存在的值。在某些情况下这很好,但不适用于GetOrCreate - 那么您必须使用std::map&lt;T&gt;::find()
  • 我在您的问题标题中读到“getOrCreate”并立即知道它的含义,所以这个名字不会那么糟糕。

标签: c# c++ design-patterns idioms


【解决方案1】:

在 C# 中...

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

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

完整代码:

扩展.AsDefaulting 可用于透明地使用任何IDictionary&lt;&gt; 作为默认值,因此您可以选择使用任何字典(甚至例如从第三方 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));

一些测试用例

包括:

【讨论】:

  • 这根本不能回答问题。
  • @MarkAmery 也有他/她的意见。我不会在这里争论。人们也关心老问题的答案质量,这很好。
【解决方案2】:

我不确定高级模式的整体编程名称,但是 Perl 有一个称为 Autovivification 的奇妙行为 - 即,当您查询 non-哈希中的现有键。

【讨论】:

    【解决方案3】:

    这在某种程度上取决于您为什么要这样做 - 我见过的成语称为 memoization、缓存、按需初始化、首次使用时创建。通常我将方法称为“ensureFoo”而不是“GetOrCreate”

    【讨论】:

      【解决方案4】:

      我总是把这样的函数称为obtainSomething()

      【讨论】:

        【解决方案5】:

        【讨论】:

        • 我不确定这是否完全是延迟加载。也许是智能延迟加载。
        • 惰性初始化或专门的惰性求值,无论哪种情况,惰性绝对是这个词。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-10-09
        • 2017-07-03
        • 2011-07-27
        • 2022-11-18
        • 1970-01-01
        • 1970-01-01
        • 2011-08-03
        相关资源
        最近更新 更多