First note that we have an overload that takes a Func<TValue>. This enables
us to call GetOrAddValue even for types that don’t support a parameterless
constructor. We pass a Func<TValue> rather than a TValue to avoid
needlessly creating empty instances when they already exist in the dictionary.
Also, since we’re using the looked-up value if it exists, we call
TryGetValue instead of checking ContainsKey.