Подтвердить что ты не робот

"GetOrCreate" - имеет ли эта идиома установленное имя?

Хорошо, рассмотрим эту общую идиому, которую большинство из нас использовали много раз (я полагаю):

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;
    }
}

Есть ли у него какое-то установленное имя?

(Да, он написан на С#, но его можно "легко" передать на С++. Следовательно, этот тег.)

4b9b3361

Ответ 2

Я всегда называю такие функции obtainSomething().

Ответ 3

Это зависит от того, почему вы это делаете - идиома - это та, которую я видел, называемой memoization, кэшированием, инициализацией по требованию, созданной при первом использовании. Обычно я вызываю метод "обеспечитьFoo", а не "GetOrCreate"

Ответ 4

Я не уверен в общем имени программирования для шаблона высокого уровня, но у Perl есть это замечательное поведение, называемое Autovivification - автоматически создавая хэш (карту) с undefined значением, когда вы запрашиваете значение несуществующего ключа в хеше.

Ответ 5

В С#...

... У меня есть DefaultingJictionary < > , который делает это. В качестве бонуса

  • вы можете указать значение по умолчанию или factory для создания значений для отсутствующих ключей:
  • он поставляется с неявным преобразованием из IDictionary < > (завершение словаря)
  • он поставляется с методами расширения для преобразования любого словаря в DefaultingDictionary < > на лету

Полный код:

Расширения .AsDefaulting могут использоваться для прозрачного использования любого IDictionary<> в качестве дефолтного, поэтому вы можете использовать любой словарь (даже, например, полученный из 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));

Некоторые тестовые примеры

: