Jones Jones - 1 month ago 14
C# Question

Is it possible to create a 'self-initializing' Dictionary extension method in C# 6.0?

Is it possible to create an extension method on a Dictionary, that is able to self-initialize if the Dictionary is null?

I'm thinking something along the lines of the following:

public static void AddOrUpdate<TKey, TValue>(this IDictionary<TKey, TValue> dictionary, TKey key, TValue value)
{
// Initialize the Dictionary if null
dictionary = dictionary ?? new Dictionary<TKey, TValue>();

// Update or insert value
dictionary[key] = value;
}


Practical use example:

// null Dictionary
Dictionary<string, string> dict = null;

// Self-initializing
dict.AddOrUpdate("Key", "Value");


Or as a property:

// Self-initializing
class.nullDict.AddOrUpdate("Key", "Value");

Answer

What you're asking for is discussed in How can I get an extension method to change the original object?, and the outcome is: in the case of a reference type, all you can do is manipulate the object. You can't assign it, because then you'll be working on a local copy and not the object originally passed into the method:

public static void Foo(this Object bar)
{
    // assignment
    bar = new ...();

    // here you're NOT calling Baz() on the object passed into the method
    bar.Baz();
}

Note that those are reference type semantics. You can't even do anything meaningful to value types:

public static void PlusOne(this int number)
{
    number++;
}

This will never modify the original value, as those are passed by value by definition: this extension method operates on a copy of the value it was called with.

That being said, this is more a question about expectations. Anyone reading this code:

Dictionary<string, string> dict = null;
dict.AddOrUpdate("Key", "Value");

Would expect either a NullReferenceException (if AddOrUpdate() were a member method of Dictionary<TKey, TValue>) or an ArgumentNullException in the case of an extension method, and even the compiler would expect that.

There's an underlying reason you think you need this. Sure, implementing the answers that say "return the new or updated dictionary from the extension method and assign at every modification" works, but gives you an awfully clumsy syntax:

Dictionary<string, string> dict = null;
dict = dict.AddOrUpdate("Key", "Value");

And you'll only have to forget the unusual dict = once to get a NRE/ANE at some point beyond its usage. That's maybe fine if you're into functional programming, but C# is not that.

So: make sure that the dictionary is initialized before trying to add key-value pairs and the need for all this unusualness goes away. It may be as simple as this:

Dictionary<string, string> dict = possiblyNullVariable ?? new Dictionary<string, string>();
Comments