2

I have an async method with the following signiature:

public async Task UpdateMerchantAttributes(UpdateMerchantRequestModel model). 

The model only has one property:

public Dictionary<string, string> Attributes { get; set; }

For a while I was calling it in a test in the following way:

await client.UpdateMerchantAttributes(new UpdateMerchantRequestModel { Attributes = 
    {
        {"businessType", "0"}
    }
});

This compiled just fine, but caused a NullReferenceException at runtime on that line. I was confused about this because client was not null, and nothing else is referenced in that line (or so it seems at a glance). Then I tried adding an explicit Dictionary declaration, like so:

await client.UpdateMerchantAttributes(new UpdateMerchantRequestModel { Attributes =
    new Dictionary<string, string>
    {
        {"businessType", "0"}
    }
});

And now it passes fine. It was my mistake, but this mistake would've cost me much less time if it'd been a compile error rather than a runtime null ref exception. So I'm curious, why does this happen? Does the compiler think that I'm trying to define a dynamic and that somehow resolves to null?

mjwills
  • 23,389
  • 6
  • 40
  • 63
Jansky
  • 1,455
  • 1
  • 17
  • 33

1 Answers1

7

The first form:

Attributes = 
    {
        {"businessType", "0"}
    }
}

is syntactic sugar for .Add(key, value). That is all. It isn't concerned with creating the dictionary (so, in effect, you are adding to a null dictionary).

Your second form is one way to solve it. Another, slightly more bulletproof way (since it protects you against the first form), is to use @MarcGravell's suggestion:

public Dictionary<string, string> Attributes
    { get; } = new Dictionary<string,string>(); // set; after the get; is also OK

or to populate Attributes in the constructor.

mjwills
  • 23,389
  • 6
  • 40
  • 63