web-dev-qa-db-fra.com

Argument Exception "Un élément avec la même clé a déjà été ajouté"

Je continue à recevoir une erreur avec le code suivant:

Dictionary<string, string> rct3Features = new Dictionary<string, string>();
Dictionary<string, string> rct4Features = new Dictionary<string, string>();

foreach (string line in rct3Lines) 
{
    string[] items = line.Split(new String[] { " " }, 2, StringSplitOptions.None);

    rct3Features.Add(items[0], items[1]);

    ////To print out the dictionary (to see if it works)
    //foreach (KeyValuePair<string, string> item in rct3Features)
    //{
    //    Console.WriteLine(item.Key + " " + item.Value);
    //}

}

L'erreur jette un ArgumentException disant:

"Un élément avec la même clé a déjà été ajouté."

Je ne suis pas sûr, après plusieurs recherches Google, de résoudre ce problème.

Plus tard dans le code, je dois accéder au dictionnaire pour une fonction de comparaison:

Compare4To3(rct4Features, rct3Features);

public static void Compare4To3(Dictionary<string, string> dictionaryOne, Dictionary<string, string> dictionaryTwo)
{
    //foreach (string item in dictionaryOne)
    //{

    //To print out the dictionary (to see if it works)
    foreach (KeyValuePair<string, string> item in dictionaryOne)
    {
        Console.WriteLine(item.Key + " " + item.Value);
    }

        //if (dictionaryTwo.ContainsKey(dictionaryOne.Keys)
        //{
        //    Console.Write("True");
        //}
        //else
        //{
        //    Console.Write("False");
        //}
    //}
}

Cette fonction n'est pas terminée, mais j'essaie de résoudre cette exception. Comment puis-je corriger cette erreur d'exception et conserver l'accès au dictionnaire pour pouvoir l'utiliser avec cette fonction? Merci

22
Jason W

Cette erreur est assez explicite. Les clés de dictionnaire sont uniques et vous ne pouvez pas avoir plus d'une clé identique. Pour résoudre ce problème, vous devez modifier votre code comme suit:

Dictionary<string, string> rct3Features = new Dictionary<string, string>();
Dictionary<string, string> rct4Features = new Dictionary<string, string>();

foreach (string line in rct3Lines) 
{
    string[] items = line.Split(new String[] { " " }, 2, StringSplitOptions.None);

    if (!rct3Features.ContainsKey(items[0]))
    {
        rct3Features.Add(items[0], items[1]);
    }

    ////To print out the dictionary (to see if it works)
    //foreach (KeyValuePair<string, string> item in rct3Features)
    //{
    //    Console.WriteLine(item.Key + " " + item.Value);
    //}
}

Cette simple instruction if garantit que vous essayez uniquement d’ajouter une nouvelle entrée au dictionnaire lorsque la clé (items[0]) n'est pas déjà présent.

33
Jdinklage Morgoone

Comme d’autres l’ont dit, vous ajoutez la même clé plusieurs fois. S'il ne s'agit PAS d'un scénario valide, vérifiez la réponse de Jdinklage Morgoone (qui n'enregistre que la première valeur trouvée pour une clé) ou envisagez cette solution de contournement (qui n'enregistre que la dernière valeur trouvée pour une clé):

// This will always overwrite the existing value if one is already stored for this key
rct3Features[items[0]] = items[1];

Sinon, s’il est valide d’avoir plusieurs valeurs pour une même clé, vous devriez envisager de stocker vos valeurs dans un fichier List<string> pour chaque clé string.

Par exemple:

var rct3Features = new Dictionary<string, List<string>>();
var rct4Features = new Dictionary<string, List<string>>();

foreach (string line in rct3Lines)
{
    string[] items = line.Split(new String[] { " " }, 2, StringSplitOptions.None);

    if (!rct3Features.ContainsKey(items[0]))
    {
        // No items for this key have been added, so create a new list
        // for the value with item[1] as the only item in the list
        rct3Features.Add(items[0], new List<string> { items[1] });
    }
    else
    {
        // This key already exists, so add item[1] to the existing list value
        rct3Features[items[0]].Add(items[1]);
    }
}

// To display your keys and values (testing)
foreach (KeyValuePair<string, List<string>> item in rct3Features)
{
    Console.WriteLine("The Key: {0} has values:", item.Key);
    foreach (string value in item.Value)
    {
        Console.WriteLine(" - {0}", value);
    }
}
8
Rufus L

Pour illustrer le problème que vous rencontrez, examinons du code ...

Dictionary<string, string> test = new Dictionary<string, string>();

test.Add("Key1", "Value1");  // Works fine
test.Add("Key2", "Value2");  // Works fine
test.Add("Key1", "Value3");  // Fails because of duplicate key

La raison pour laquelle un dictionnaire a une paire clé/valeur est une fonctionnalité afin que vous puissiez le faire ...

var myString = test["Key2"];  // myString is now Value2.

Si Dictionary avait 2 Key2, il ne saurait pas laquelle renvoyer, il vous limite donc à une clé unique.

4
Scottie

Si vous voulez "insérer ou remplacer" une sémantique, utilisez cette syntaxe:

A[key] = value;     // <-- insert or replace semantics

Il est plus efficace et lisible que les appels impliquant "ContainsKey ()" ou "Remove ()" avant "Add ()".

Donc dans votre cas:

rct3Features[items[0]] = items[1];
3
Tim Cooper

Cette exception est levée s'il y a déjà une clé dans le dictionnaire lorsque vous essayez d'ajouter la nouvelle.

Il doit y avoir plus d'une ligne dans rct3Lines avec le même premier mot. Vous ne pouvez pas avoir 2 entrées dans le même dictionnaire avec la même clé.

Vous devez décider ce que vous voulez qu'il se passe si la clé existe déjà - si vous voulez simplement mettre à jour la valeur là où la clé existe, vous pouvez simplement

rct3Features[items[0]]=items[1]

mais sinon, vous voudrez peut-être tester si la clé existe déjà avec:

if(rect3Features.ContainsKey(items[0]))
{
    //Do something
} 
else 
{
    //Do something else
}
3
Stewart_R