Argument Exception “Item with Same Key has already been added”

yguyon28
yguyon28 used Ask the Experts™
on
I'm running into this error message when I'm calling this following method...

Argument Exception “Item with Same Key has already been added”

        public static Dictionary<string, int> GetOrdinals(this SqlDataReader reader)
        {
            Dictionary<string,int> returnDictionary = new Dictionary<string, int>();

           

            for (int i = 0; i < reader.FieldCount; i++)
            {
                returnDictionary.Add(reader.GetName(i).Trim().ToUpper(), i);
            }
            return returnDictionary;
        }

Open in new window



I was trying to write the following logic but I do get lost...

    if (returnDictionary.ContainsKey(....) then don't add it....


I changed my logic as follow:


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

           

            for (int i = 0; i < reader.FieldCount; i++)
            {

                if (!returnDictionary.ContainsKey(reader.GetName(i).Trim().ToUpper()))
                {
                    returnDictionary.Add(reader.GetName(i).Trim().ToUpper(), i);
                }
               
                   
            }
            return returnDictionary;
Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
Most Valuable Expert 2015
Commented:
Use ContainsKey() to check if the key doesn't exist, and if not add it...

 for (int i = 0; i < reader.FieldCount; i++)
 {
       string name = reader.GetName(i).Trim().ToUpper();
       if (!returnDictionary.ContainsKey(name)) {
          returnDictionary.Add(name, i);
       }
 }

Open in new window

Retired
Distinguished Expert 2017
Commented:
Hi yguyon28;

Try it like this.
public static Dictionary<string, int> GetOrdinals(this SqlDataReader reader)
{
    Dictionary<string,int> returnDictionary = new Dictionary<string, int>();   

    for (int i = 0; i < reader.FieldCount; i++)
    {
		var name = reader.GetName(i).Trim().ToUpper();
		if !returnDictionary.ContainsKey(TKey) then
			returnDictionary.Add(name, i);        	
    }
	
    return returnDictionary;
}

Open in new window

Commented:
Hi yguyon28,

Dictionary keys are unique and you cannot add more than one of the same key name. So, you have check the key which you are going to add to dictionary already exists or not. If not exists then you add to the dictionary.
Fundamentals of JavaScript

Learn the fundamentals of the popular programming language JavaScript so that you can explore the realm of web development.

Top Expert 2016
Commented:
I was trying to write the following logic but I do get lost...

    if (returnDictionary.ContainsKey(....) then don't add it....
I changed my logic as follow: ...

can you tell where you got lost? as far as i can see all given solutions are equivalent to your 'changed logic' code ...

the only thing you should change is to use a tempory string for the name to add as shown by _agx_ and Fernando in order to avoid a duplicate usage of the expression

string name = reader.GetName(i).Trim().ToUpper();

Open in new window


Sara
Most Valuable Expert 2015

Commented:
>> as far as i can see all given solutions are equivalent to your 'changed logic' code ...

They're very similar, but the solutions added not equals, "!", which changes the meaning of the expression.  

By testing the true condition first, you also need an else clause, which is kind of awkward .... That may be what tripped them up.

             // key exists
             if (returnDictionary.ContainsKey(....))
                  /* do nothing here */
             // doesn't exist
             else
                  /* add key here */

Simpler to just test if the condition evaluates to false

             if (!returnDictionary.ContainsKey(....))
                  /* add key here */
Top Expert 2016

Commented:
but the solutions added not equals, "!",

no, the changed code in the original post also uses the not ! operator:

//   v
if ( !  returnDictionary.ContainsKey(reader.GetName(i).Trim().ToUpper()))

Open in new window


the ! easily can be overseen. that's why i always would change the condition like

if ( returnDictionary.ContainsKey(reader.GetName(i).Trim().ToUpper()) == false)

Open in new window


what is much better readable.

Sara
Most Valuable Expert 2015

Commented:
I'm running into this error message when I'm calling this following method...

Argument Exception “Item with Same Key has already been added”
.....

No, I mean the formatted code below the error message which doesn't include it.  I don't think they really changed the code (or maybe they forgot to compile) because if they had, the error wouldn't have occurred :)

>> what is much better readable.

I'd prefer to add white space. Though perfectly valid, I just don't like the verbosity of "== false" :-)
Top Expert 2016

Commented:
I just don't like the verbosity of "== false"

the "verbosity"  is really necessary here as you can see from your own comment:

I mean the formatted code below the error message which doesn't include it.

where the formatted code of the original post doesn't include an if statement at all and the missing NOT operator only was in the following non-formatted text.

before i added my first comment I double-checked all statements made because it is so easy to go wrong ...  ;-)

Sara
Most Valuable Expert 2015

Commented:
>> the "verbosity"  is really necessary here

No, necessary means required to function. Using "== false" isn't necessary. While I can see why you prefer it, it's still just a matter of personal preference, not a requirement ;-)

>> as you can see from your own comment:
No, that's just me doing too many things, skimming the thread text and making a mistake. My bad!

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial