2

Reading the accepted answer of C# Java HashMap equivalent, it literary states:

C#'s Dictionary uses the Item property for setting/getting items:

  • myDictionary.Item[key] = value
  • MyObject value = myDictionary.Item[key]

And when trying to implement it, I get an error when using:

myDictionary.Item[SomeKey] = SomeValue;

Error: CS1061 'Dictionary' does not contain a definition for 'Item'

And I will need to use a myDictionary.Add(SomeKey, SomeValue); instead same as this answer and MSDN - Dictionary in order to resolve the error.

The code is fine, but out of curiosity am I doing anything wrong? Other than one does not compile, what is the difference between

Dictionary.Item[SomeKey] = SomeValue; 

and

Dictionary.Add(SomeKey, SomeValue);

Edit:

I edited the accepted answer in C# Java HashMap equivalent. See edition history to know why.

Community
  • 1
  • 1
Khalil Khalaf
  • 9,259
  • 11
  • 62
  • 104
  • 4
    The later will throw DuplicateKeyException if the dictionary already contains SomeKey, while the former will not. Think of it like AddOrUpdate. – Ivan Stoev Sep 22 '16 at 15:37
  • This first : Dictionary.Item[SomeKey] = SomeValue; is to change a values already in the dictionary. The other is to add new items to dictionary. – jdweng Sep 22 '16 at 15:37
  • 3
    As for your error, just omit Item, like this: myDictionary[SomeKey] = SomeValue; – Evk Sep 22 '16 at 15:38
  • 5
    The actual syntax would be `Dictionary[SomeKey] = SomeValue;`. You don't use the `.Item` property. – Tim Sep 22 '16 at 15:38
  • Then [**the accepted answer**](http://stackoverflow.com/questions/1273139/c-sharp-java-hashmap-equivalent/1273149#1273149) has a typo mistake. Dictionary does not have a definition for `item`. Thank you – Khalil Khalaf Sep 22 '16 at 15:39
  • @OleksandrPshenychnyy It literally states `C#` and `Item` Property. – Khalil Khalaf Sep 22 '16 at 15:41
  • 3
    Well it's not exactly a typo, because indexer ([] <- this one) is really compiled to a property named 'Item' (unless stated otherwise), so that other languages are able to access it. You can read more about it here: https://msdn.microsoft.com/en-us/library/2549tw02.aspx – Evk Sep 22 '16 at 15:43
  • @Evk I think you are right. Could you wrap all in a nice answer? Thanks for the explanation :) – Khalil Khalaf Sep 22 '16 at 15:52

2 Answers2

2

I think the difference is:

  • Dictionary[SomeKey] = SomeValue; (not Dictionary.Item[SomeKey] = SomeValue;) will add new key value pair if the key does not exist, if the key existed, it will replace the value
  • Dictionary.Add(SomeKey, SomeValue); will add new key value pair, and if the key already existed, it will throw Argument Exception: An item with the same key has already been added

The example is:

try
{
     IDictionary<int, string> dict = new Dictionary<int, string>();

     dict.Add(0, "a");
     dict[0] = "b";  // update value to b for the first key
     dict[1] = "c";  // add new key value pair
     dict.Add(0, "d"); // throw Argument Exception
 }
 catch (Exception ex)
 {
     MessageBox.Show(ex.Message);
 }
Khalil Khalaf
  • 9,259
  • 11
  • 62
  • 104
1

Difference is simple

Dictionary[SomeKey] = SomeValue; // if key exists already - update, otherwise add
Dictionary.Add(SomeKey, SomeValue); // if key exists already - throw exception, otherwise add

As for the error

Error: CS1061 'Dictionary' does not contain a definition for 'Item'

C# allows for "default" indexer, but how it should be implemented internally? Remember that there are many languages working with CLR, not just C#, and they would also need a way to call that indexer.

CLR has properties, and it also allows to provide arguments when those properties getters or setters are called, because properties are really compiled as a pair of get_PropertyName() and set_PropertyName() methods. So, indexer can be represented by a property which getter and setter accept additional arguments.

Now, there cannot be property without a name, so we need to choose a name for the property which represents our indexer. By default, "Item" property is used for the indexer property, but you can overwrite it with IndexerNameAttribute.

Now when indexer is represented as regular named property, any CLR language can called it with get_Item(index).

That's why in article you linked that indexer is referenced by Item. Though when you use it from C#, you have to use appropriate syntax and just call it as

Dictionary[SomeKey] = SomeValue;
Evk
  • 98,527
  • 8
  • 141
  • 191
  • I just found this: [Different ways of adding to Dictionary](http://stackoverflow.com/questions/1838476/different-ways-of-adding-to-dictionary) which I think is worth mentioning as an extra for knowing what is the actual difference between the two, despite the error. Thank you again :) – Khalil Khalaf Sep 22 '16 at 16:16