Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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");
like image 673
Jones Avatar asked Nov 20 '25 08:11

Jones


2 Answers

No

For this to work, you would have to pass your parameter by ref and that is not allowed.

When the this keyword modifies the first parameter of a static method, it signals to the compiler that the method is an extension method. No other modifiers are needed or allowed on the first parameter of an extension method.

like image 193
nvoigt Avatar answered Nov 22 '25 21:11

nvoigt


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>();
like image 21
CodeCaster Avatar answered Nov 22 '25 22:11

CodeCaster