1

I am trying to use TryGetValue on a Dictionary as usual, like this code below:

Response.Context.Skills[MAIN_SKILL].UserDefined.TryGetValue("action", out var actionObj)

My problem is the dictionary itself might be null. I could simply use a "?." before UserDefined but then I receive the error:

"cannot implicitly convert type 'bool?' to 'bool'"

What is the best way I can handle this situation? Do I have to check if UserDefined is null before using TryGetValue? Because if I had to use Response.Context.Skills[MAIN_SKILL].UserDefined twice my code could look a little messy:

if (watsonResponse.Context.Skills[MAIN_SKILL].UserDefined != null && 
    watsonResponse.Context.Skills[MAIN_SKILL].UserDefined.TryGetValue("action", out var actionObj))
{
    var actionName = (string)actionObj;
}
Alexandre Paiva
  • 304
  • 3
  • 13

2 Answers2

6

Add a null check (?? operator) after the bool? expression:

var dictionary = watsonResponse.Context.Skills[MAIN_SKILL].UserDefined;
if (dictionary?.TryGetValue("action", out var actionObj)??false)
{
    var actionName = (string)actionObj;
}
Nigel
  • 2,961
  • 1
  • 14
  • 32
  • Thanks! That actually solved my problem. But I still receive a ```Use of unassigned local variable 'actionObj'```... is my only option here to declare that object before the ```if``` statement? – Alexandre Paiva Jan 06 '22 at 22:03
  • 1
    @AlexandrePaiva Yes you would have to do so. If you think about the logic you will see why that error is thrown – Charlieface Jan 06 '22 at 22:07
  • @Charlieface yeah, I'll declare the object before then. Just for feature reference, I found a question with a interesting discussion regarding the use of local variables inside the TryGetValue: https://stackoverflow.com/questions/56779825/why-compiler-throw-error-cs0165-use-of-unassigned-local-variable – Alexandre Paiva Jan 06 '22 at 22:17
3

Another option is to compare to true.

It looks slightly weird, but it works with three-valued logic and says: is this value true but not false or null

if (watsonResponse.Context.Skills[MAIN_SKILL]
    .UserDefined?.TryGetValue("action", out var actionObj) == true)
{
    var actionName = (string)actionObj;
}

You can do the opposite logic with != true: is this value not true, so either false or null

if (watsonResponse.Context.Skills[MAIN_SKILL]
    .UserDefined?.TryGetValue("action", out var actionObj) != true)
{
    var actionName = (string)actionObj;
}
Charlieface
  • 52,284
  • 6
  • 19
  • 43