Argument Exception "Элемент с тем же ключом уже добавлен"

Я получаю сообщение об ошибке со следующим кодом:

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);
    //}

}

Ошибка выдает сообщение ArgumentException,

"Элемент с тем же ключом уже добавлен."

Я не уверен, что после нескольких поисковых запросов Google исправить это.

Позже в коде мне нужно получить доступ к словарю для функции сравнения:

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");
        //}
    //}
}

Эта функция не завершена, но я пытаюсь разрешить это исключение. Каким образом я могу исправить эту ошибку исключения и сохранить доступ к словарю для использования с этой функцией? Спасибо вам

Ответы

Ответ 1

Эта ошибка довольно понятна. Словарь ключей уникален, и у вас не может быть более одного ключа. Чтобы исправить это, вы должны изменить свой код следующим образом:

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);
    //}
}

Этот простой оператор if гарантирует, что вы только пытаетесь добавить новую запись в словарь, если ключ (items[0]) еще не присутствует.

Ответ 2

Как говорили другие, вы добавляете один и тот же ключ более одного раза. Если это НЕ правильный сценарий, тогда проверьте ответ Jdinklage Morgoone (который сохраняет только первое значение, найденное для ключа), или рассмотрите этот способ обхода (который сохраняет только последнее значение, найденное для ключа):

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

В противном случае, если допустимо иметь несколько значений для одного ключа, вам следует рассмотреть возможность сохранения ваших значений в List<string> для каждого string.

Например:

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);
    }
}

Ответ 3

Чтобы проиллюстрировать возникшую у вас проблему, давайте посмотрим на некоторый код...

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

Причина, по которой словарь имеет пару ключ/значение, является функцией, поэтому вы можете это сделать...

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

Если словарь имел 2 Key2, он не знал бы, какой из них нужно вернуть, поэтому он ограничивает вас уникальным ключом.

Ответ 4

Это исключение вызывается, если в словаре уже есть ключ, когда вы пытаетесь добавить новый.

В rct3Lines должно быть более одной строки с тем же самым первым словом. У вас не может быть 2 записи в одном словаре с одним и тем же ключом.

Вам нужно решить, что вы хотите, если ключ уже существует - если вы хотите просто обновить значение, в котором существует ключ, вы можете просто

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

но если вы не захотите проверить, существует ли ключ с помощью:

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

Ответ 5

Сбросьте словарь перед добавлением к нему каких-либо элементов. Я не знаю, как словарь одного объекта влияет на другого во время назначения, но я получил ошибку после создания другого объекта с теми же ключами, парами значений.

NB: Если вы собираетесь добавлять элементы в цикле, просто убедитесь, что вы очистили словарь перед входом в цикл.