Search code examples
c#.netconcurrencycontainersconcurrentdictionary

ArgumentNullException in ConcurrentDictionary.AddOrUpdate


I am getting some weird behavior when calling AddOrUpdate method of the ConcurrentDictionary:

static void Main(string[] args)
{
    var t = new ConcurrentDictionary<string, object>();
    t.AddOrUpdate("boo", null, (k, v) => null);
}

throws ArgumentNullException:

System.ArgumentNullException was unhandled
  HResult=-2147467261
  Message=Value cannot be null.
Parameter name: addValueFactory
  ParamName=addValueFactory
  Source=mscorlib
  StackTrace:
       at System.Collections.Concurrent.ConcurrentDictionary`2.AddOrUpdate(TKey key, Func`2 addValueFactory, Func`3 updateValueFactory)
       at ConcurrentDictionaryTest.Program.Main(String[] args)

Why? Am I not allowed to add null's as values to concurrent dictionary? Documentation does not say anything special about null as value and following works fine:

static void Main(string[] args)
{
    var t = new ConcurrentDictionary<string, object>();
    const object defaultValue = null;
    t.AddOrUpdate("boo", defaultValue, (k, v) => defaultValue);
}

So, what's going on?


Solution

  • See the documentation for the overload you are using. The second argument is supposed to be a function invoked when the key doesn't exist. You're free to return null from this function, but you still have to provide it.

    t.AddOrUpdate("boo", k => null, (k, v) => null);
    

    If you want to use the other overload you can use casting:

    t.AddOrUpdate("boo", (object)null, (k, v) => null);