Using Linq to objects, how to create an empty dictionary of <string, string> easily?
To create an empty sequence one uses the following
var empty = Enumerable.Empty<string> ();
Is there an equivalent for creating an empty dictionary as easily as this?
Back to year 2019, there is a way to achieve this, using:
ImmutableDictionary<TKey, TValue>.Empty
More info can be found here (last couple of posts): https://github.com/dotnet/corefx/issues/25023
No there is no equivalent...
The purpose of Enumerable.Empty<T>()
is to return a "cached" instance of an empty array. So you can avoid the overhead of creating a new array (return new T[0];
).
You cannot translate this to a non-readonly structure like a IDictionary<TKey, TValue>
or Dictionary<TKey, TValue>
since the returned instance might be modified later and would therefore invalidate the purpose...
What's wrong with new Dictionary<string, string>()
?
I assume that (at least now 5 years later) empty dictionary really means empty read-only dictionary. This structure is just as useful as an empty enumerable sequence. For instance you might have a configuration type that has a dictionary property (think JSON) that cannot be modified once it has been configured:
public class MyConfiguration
{
public IReadOnlyDictionary<string, string> MyProperty { get; set; }
}
However, what if the property is never configured? Then MyProperty
is null
. A good solution to avoiding an unexpected NullReferenceException
is to initialize the property with an empty dictionary:
public class MyConfiguration
{
public IReadOnlyDictionary<string, string> MyProperty { get; set; }
= new Dictionary<string, string>();
}
The downside is that each allocation of MyConfiguration
requires an allocation of an empty dictionary. To avoid this you need something similar to Enumerable.Empty<T>()
, i.e. a cached empty read-only dictionary.
There are two ways to achieve this. The first is to take a dependency on System.Collections.Immutable. An ImmutableDictionary<TKey, TValue>
implementes IReadOnlyDictionary<TKey, TValue>
and it has an Empty
field that you can use:
IReadOnlyDictionary<string, string> empty = ImmutableDictionary<string, string>.Empty;
Or you can implement your own empty read-only dictionary similar to Enumerable.Empty<T>()
and Array.Empty<T>()
. Notice how the empty value is no longer a field and that the class is not generic. Instead it is a generic method. This requires two classes.
The first class is "hidden" and can be internal:
internal static class EmptyReadOnlyDictionary<TKey, TValue>
{
public static readonly IReadOnlyDictionary<TKey, TValue> Instance
= new Dictionary<TKey, TValue>();
}
The second class uses the first class but hides it behind the IReadOnlyDictionary<TKey, TValue>
interface:
public static class ReadOnlyDictionary
{
public static IReadOnlyDictionary<TKey, TValue> Empty<TKey, TValue>()
=> EmptyReadOnlyDictionary<TKey, TValue>.Instance;
}
Usage:
IReadOnlyDictionary<string, string> empty = ReadOnlyDictionary.Empty<string, string>();
For both solutions there will only be a single empty dictionary instance for each distinct combination of TKey
and TValue
.