19

Ok, consider this common idiom that most of us have used many times (I assume):

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

Does it have any kind of established name?

(Yes, it's written in C#, but it can be "easily" transferred to C++. Hence that tag.)

Johann Gerell
  • 24,991
  • 10
  • 72
  • 122
  • 2
    I always call it exactly that: GetOrCreate. – Joren Sep 22 '09 at 20:25
  • 4
    Doing C++, I always seem to have to use `std::map::find()` because that stupid `std::map::operator[]()` adds missing values and I just want to find those already there. Doing C#, I always seem to need "get-or-create" and have to write the above, since no operation as easy as that beautiful `std::map::operator[]()` is available. Isn't that strange? – sbi Sep 22 '09 at 20:26
  • Similar: http://stackoverflow.com/questions/1238386/function-name-for-creating-something-if-its-not-there-yet/1238547#1238547 – Tom Dalling Sep 23 '09 at 00:02
  • @sbi: Not only does `std::map::operator[]()` add missing values, it also replaces what was already there. In some cases that's fine, but not for `GetOrCreate` - then you **must** use `std::map::find()`. – Johann Gerell Sep 23 '09 at 07:08
  • @Johann: It only replaces if you write to the reference handed out by `std::map::operator[]()`. If you just read from it, this doesn't happen. – sbi Sep 23 '09 at 09:06
  • @sbi: Except for the first time it's used, then it'll insert the default value for the `second` type, so by querying the map using `[]` you cannot know if it's a new or old value. – Johann Gerell Sep 23 '09 at 09:58
  • @Johann: Yep. But sometimes that's fine. (Like when `Value` is a container itself, to which you want to add something.) Just today I wrote an extension method `public static Value GetOrCreate(this IDictionary dict, Key key)`. I feel much better now. `:)` – sbi Sep 24 '09 at 23:28
  • 4
    I read "getOrCreate" in your question title and knew immediately what it meant, so the name can't be that bad. – finnw Jul 14 '10 at 09:35
  • I think you should just call it "GetValue" because you're ensuring it. It doesn't matter if it needs to be created or is already there, because the result is the same. – 0xbadf00d Jun 13 '11 at 19:24
  • I usually use 'void ensureXXXX();' before/while accessing if I ever need something like this. But in the case of lazy accessors, I can live with just calling it e.g. 'T const& getXXX() const'. After all, that's what we have encapsulation _for_ in the fist place – sehe May 25 '12 at 18:37

4 Answers4

9

I always call such functions obtainSomething().

alex tingle
  • 6,920
  • 3
  • 25
  • 29
9

It sort of depends why you're doing it - the idiom is one I've seen be called memoization, caching, initialisation on demand, create on first use. Normally I call the method "ensureFoo" rather than "GetOrCreate"

Pete Kirkham
  • 48,893
  • 5
  • 92
  • 171
4

Lazy Loading

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

jagprinderdeep
  • 396
  • 1
  • 4
1

I'm unsure of overall programming name for the high level pattern, but Perl has this wonderful behavior called Autovivification - namely, automatically creating hash (map) key with undefined value when you're querying the value of non-existing key in the hash.

DVK
  • 126,886
  • 32
  • 213
  • 327