Why TryGetValue deallocates my Dictionary ?
-
13-03-2021 - |
Domanda
I have this piece of code :
Dictionary<string, object> tempDict = new Dictionary<string, object>();
if(xDicionary.TryGetValue(...., out tempDict)
{
tempDict.Add(...);
}
else
{
tempDict.Add(..);
}
If the code passes to the else block then I got and exception that cannot perform add because tempDict points to null. Why is this happening ? I know how to bypass it in an ugly way by allocating new Dictionary also in the else block but is there any better way of doing this ?
Soluzione
Because methods that have an out
parameter, must assign a value to the out
parameter. That means that when you call xDicionary.TryGetValue
tempDict
is always overwritten, and when nothing is found, it is set to null. Therefore, in your else, tempDict
will always be null.
Altri suggerimenti
That's how TryGetValue
works because it uses an out
parameter. An out
parameter is always assigned a value in a method and so whatever you initialise the parameter to, it will be overwritten.
The documentation makes this point by stating:
This parameter is passed uninitialized.
So you have to use a temporary.
TryGetValue
will return false and set the tempDict
to null
if it could not get the value.
This happens because an out
parameter must be definitely assigned in the method being called, and when a value can't be retried for a value type, null
is the logical default to assign to it.
This is the normal semantics of all BCL TryGet*
methods.
Because if xDictionary
does not contain the value requested, TryGetValue
returns false
and the out
value is set to null
. Hence, when you try do Add
something to null
you get NullReferenceException
.
You should put tempDict = new ... within the else {} block. If TryGetValue returns false then you cannot rely on the value in the out parameter.