1

I couldn't find a relevant thread on this topic, so I decided to ask a new question. I'm at my first steps in the Dictionary class in C#, and I have several basic questions. First off, what the difference between this:

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

    dict[1] = "hello";

and this (if any):

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

    dict.Add(1, "hello");

My second question is: is there any way to add multiple entries (if I can call a pair of key and value that way) on the same line. Something like int a, b, c;, instead of int a; int b; int c;. Or is it only possible to add them on multiple lines:

dict.Add(1, "hello");
dict.Add(2, "hey");

My last question, concerning the output of a dictionary, is if there is a "better" way to print a dictionary, instead of doing it that way:

foreach (KeyValuePair<int, string> pair in dict)
    {
        Console.WriteLine("{0}: {1}", pair.Key, pair.Value);
    }

I mean "better" in terms of faster to type and faster to execute. (I know that it also works with var, instead of KeyValuePair<>.

Boyan Kushlev
  • 1,043
  • 1
  • 18
  • 35
  • don't worry too much regarding typing. Visual Studio can select text "vertically" (by holding down SHIFT **and** ALT), which becomes handy in situations such as needing to type/edit many almost identical lines. –  Dec 27 '13 at 16:49

5 Answers5

5

1. What the difference between this: dict[1] = "hello" and this: dict.Add(1, "hello")?

Yes, there is a difference between using Add and [] indexer property.

You can call dict[1] = "hello"; as many times as you want, but you can call dict.Add(1, "hello"); only once. Otherwise it will throw ArgumentException saying An item with the same key has already been added.

2. Is there any way to add multiple entries (if I can call a pair of key and value that way) on the same line.

You can only add multiple items in one line using collection initialization syntax, when Dictionary is created:

Dictionary<int, StudentName> students = new Dictionary<int, StudentName>()
{
    { 111, new StudentName {FirstName="Sachin", LastName="Karnik", ID=211}},
    { 112, new StudentName {FirstName="Dina", LastName="Salimzianova", ID=317}},
    { 113, new StudentName {FirstName="Andy", LastName="Ruth", ID=198}}
};

But, it will be transformed to Add method calls by compiler anyway :)

Read How to: Initialize a Dictionary with a Collection Initializer (C# Programming Guide)

3. Is if there is a "better" way to print a dictionary, instead of doing it that way:

There is a way to print dictionary using one line expression, but I don't think it's more readable and it will use foreach loop internally anyway, so wan't be faster either:

 Console.WriteLine(string.Join(Environment.NewLine, dict.Select(x => string.Format("{0}: {1}", x.Key, x.Value))));
MarcinJuraszek
  • 124,003
  • 15
  • 196
  • 263
2

First two snippets are equivalent is the key is not present in the dictionary, as can be found in the documentation:

The value associated with the specified key. If the specified key is not found, a get operation throws a KeyNotFoundException, and a set operation creates a new element with the specified key.

If the key is present Add will throw:

In contrast, the Add method throws an exception if a value with the specified key already exists.

The second question is answered here:

Dictionary<int, StudentName> students = new Dictionary<int, StudentName>()
{
    { 111, new StudentName {FirstName="Sachin", LastName="Karnik", ID=211}},
    { 112, new StudentName {FirstName="Dina", LastName="Salimzianova", ID=317}},
    { 113, new StudentName {FirstName="Andy", LastName="Ruth", ID=198}}
};

The last question is subjective, it can be made a bit simpler then your snippet though using var:

foreach (var entry in dictionary)
    Console.WriteLine("[{0} {1}]", entry.Key, entry.Value); 
BartoszKP
  • 34,786
  • 15
  • 102
  • 130
2

First off, what the difference between this dict[1] = "hello" and dict.Add(1, "hello")

In practice, there's no major difference. [] is an indexer and in effect it just calls Add() internally. However, being an indexer it can replace the value when the key already exists in the dictionary.

My second question is: is there any way to add multiple entries (if I can call a pair of key and value that way) on the same line

Yes, when creating a new instance, you can supply an initializer like this:

new Dictionary<int, string> { { 1, "hello" }, { 2, "world" } }

However, you should bear in mind that sometimes more lines of code are better readable than one line of code. Remember other developers reading your code (and yourself 2 weeks from now).

My last question, concerning the output of a dictionary, is if there is a "better" way to print a dictionary. … I mean "better" in terms of faster to type and faster to execute. (I know that it also works with var, instead of KeyValuePair<>.

  • Again, you shouldn't sacrifice readability over number of lines of code. Your code is good and there's no need to make it any “better”.
  • A very important rule: do not optimize prematurely, i.e. don't care of performance unless you really have a performance problem.
  • var has no impact on performance at all.
Ondrej Tucny
  • 27,626
  • 6
  • 70
  • 90
  • `dict[1] = "Hello"` will overwrite an element with the same key in the dictionary, whereas using `Add` will throw an exception in that case. So, no, the two are not the same. (I did not downvote...) –  Dec 27 '13 at 16:43
  • Does the downvoter care to comment? We are here to help, providing a reasonably elaborate answer to a beginner, and not to downvote for some corner-case omissions or simplifications. – Ondrej Tucny Dec 27 '13 at 16:43
  • @elgonzo Which is exactly what I added to my answer just a few minutes ago. – Ondrej Tucny Dec 27 '13 at 16:44
  • @elgonzo So if you are the downvoter, feel free to fix your vote or please state what else's wrong. – Ondrej Tucny Dec 27 '13 at 16:47
  • 1
    @Ondreij, i did not downvote, so i can't take it away; sorry about that. I still gave an upvote for your answer, for what it's worth... –  Dec 27 '13 at 16:50
1

Q: What the difference between this: dict[1] = "hello" and this: dict.Add(1, "hello")?

The logic behind Add and dict[something] is the same.

If you'll look at the Dictionary class source, you can see it uses the same Insert method for adding entries:

    public TValue this[TKey key] {
        get {
            // skipped
        }
        set {
            Insert(key, value, false);
        }
    }

    public void Add(TKey key, TValue value) {
        Insert(key, value, true);
    }

It works the same way, except you can call Add only once with the same key.

Q: Is if there is a "better" way to print a dictionary, instead of doing it that way

You can use:

        var dict = new Dictionary<int, string>()
        {
            { 1, "asd" },
            { 2, "zxc" },
            { 3, "qwe" }
        };

Q: Is there any way to add multiple entries (if I can call a pair of key and value that way) on the same line.

You can use simplified syntax:

        foreach (var pair in dict)
        {
            Console.WriteLine(pair);
        }

Output is:

[1, asd]
[2, zxc]
[3, qwe]
Roman Pushkin
  • 5,639
  • 3
  • 40
  • 58
  • Huh? They're actually VERY different: `Add` creates and will add the same entry only once w/o error. Accessing an entry by index won't create an entry at all, but you could use it a thousand times in a row, if the entry already exists - it would override its value again and again. – Thomas Weller Dec 27 '13 at 16:40
  • @ThomasWeller, I mentioned that. – Roman Pushkin Dec 27 '13 at 16:41
  • @ThomasWeller Accessing entry by index **will** create an entry with given key if it not exists. – MarcinJuraszek Dec 27 '13 at 16:45
0

One key difference between dict[1] = "hello"; and dict.Add(1, "hello"); is that dict.Add() will throw an ArgumentException if an item with that key already exists, while the indexer will simply overwrite the existing item. I didn't think C# had this behavior until I just tried it myself.

Regarding your second question, see this SO question for more details. Once a dictionary is constructed, you can't add multiple items at once using built-in methods. The other answers provide you ways of constructing a dictionary with multiple items at once.

For the third question, you are doing it about as well/readable as it can be done; if you feel like you are going to be doing this frequently, you perhaps would like to create an extension method:

public static class ExtensionMethods
{
    public static void PrintDictionary<TKey, TValue>(this Dictionary<TKey, TValue> dictionary)
    {
        foreach(var kvp in dictionary)
        {
            Console.WriteLine("{0}, {1}", kvp.Key, kvp.Value);
        }
    }
}

You could then simply call dict.PrintDictionary() and get your desired output.

Community
  • 1
  • 1
Sven Grosen
  • 5,616
  • 3
  • 30
  • 52