-1

I have such condition

//  `xyz` is a `dictionary<string, MyCustomType>`.
if(smth){
    xyz["ord_82"] = Func() ;// That Returns  "MyCustomType" object
}
if(xyz.ContainsKey("ord_82"){
    Print("started");
    Print(xyz["ord_82"].ToString());   // <----------------  sometimes this line throws "Object reference not set to an instance of an object"
    Print("ended");
}

I couldnt find out what could be the reason.. You see, that ContainsKey is passed, but still throws an error..

T.Todua
  • 44,747
  • 17
  • 195
  • 185
  • 2
    So did you look at what `xyz["ord_82"]` returns? Presumably it's returning null, which is perfectly valid... – Jon Skeet Sep 09 '17 at 09:53
  • 1
    For this kind of problem you should use `TryGetValue` - rather than `ContainsKey` and `[]`. It will be more performant. Changing to `TryGetValue` won't solve your problem though - you still need to read @GiladGreen 's solution. – mjwills Sep 09 '17 at 09:56
  • @mjwills thnks! – T.Todua Sep 09 '17 at 10:16

2 Answers2

3

Though the key "ord_82" exists the value mapped by it can still be null. Therefore xyz["ord_82"].ToString() can still through NullReferenceException.

Use ?. operator from C# 6.0:

Print(xyz["ord_82"]?.ToString());

Notice that this will produce null for Print's argument so you can do:

Print(xyz["ord_82"]?.ToString() ?? "");

For an earlier version of C# use the ?: operator (The ?. is just a sugar syntax to it:

var value = xyz["ord_82"];
Print(value == null ? "" : value.ToString());
Gilad Green
  • 34,248
  • 6
  • 46
  • 76
  • thanks! can you give me similar solution for net 3.5? `?.` doesnt work in 3.5 – T.Todua Sep 09 '17 at 10:12
  • 1
    @T.Todua - see update please – Gilad Green Sep 09 '17 at 11:02
  • 3
    @T.Todua: `?.` works fine with .NET 3.5 - but you need the C# 6 compiler. It's worth being very clear about the difference between *framework* features (or CLR features, indeed) and *language* features. You can very often use new language features even if you're targeting old frameworks. – Jon Skeet Sep 09 '17 at 13:46
  • @JonSkeet aah, my bad, i am newbie and didnt know these details . Most of the answers mentiod like: `...for C# 6 and later..` and I assumed that those features were for `net 4.0` and later... Now I understand, thanks! (p.s. So, i can even use C#7 features with net3.5, right? wow, good.) – T.Todua Sep 09 '17 at 16:53
0

xyz["ord_82"] = Func() ;// That Returns "MyCustomType" object

Check if Func() is returning null object of MyCustomType

xyz["ord_82"].ToString() is called on the value returned by xyz["ord_82"] which is null and .ToString() on null will throw "Object reference not set to an instance of an object" exception which is NullReferenceException

So your code either should be changed like:

    //  `xyz` is a `dictionary<string, MyCustomType>`.
    if(smth){
     var obj = Func(); // That Returns  "MyCustomType" object
     if(obj != null) {
      xyz["ord_82"] = obj;
     }
    }

or like:

MyCustomType val = null;
if(xyz.TryGetValue("ord_82", out val)){
     Print("started");
     Print(val.ToString());
     Print("ended");
    }

Corrections edited. Thanks @mjwills for the pointers

rAhulD
  • 41
  • 6
  • Your second code block does a hash lookup three times - when if you used `TryGetValue` you would only need one (i.e. much faster). – mjwills Sep 09 '17 at 10:35
  • That's true, there are numerous ways to optimize this code. – rAhulD Sep 11 '17 at 05:11