C#でディクショナリを使用した処理を記述する際、以下のようなエラーに遭遇することがあります。
System.ArgumentException: '同一のキーを含む項目が既に追加されています。'
本記事では、上記エラーの対処方法について紹介します。
エラーが発生する原因とサンプルコード
このエラー(例外)は、ディクショナリに対して、同一のキーを再度追加しようとした場合に発生します。
以下は、エラー「同一のキーを含む項目が既に追加されています。」を再現するためのサンプルコードです。
using System;
using System.Collections.Generic;
class Program
{
static void Main()
{
// ディクショナリの初期化
Dictionary<string, int> fruits = new Dictionary<string, int>
{
{"apple", 1},
{"banana", 2},
{"cherry", 3}
};
// ★System.ArgumentException: '同一のキーを含む項目が既に追加されています。'
fruits.Add("apple", 4); // appleは既に登録されている
}
}
解決方法はシナリオにより異なる
エラーを修正する前に、エラーがなぜ発生したのかを考えましょう。そのためには、ディクショナリ fruits が、どのように扱われる設計だったのかを知る必要があります。
以下に2つのシナリオと、それぞれの修正方法を示します。
ディクショナリ fruits が名称と個数を保持する目的の場合
このケースでは、”apple”は1個、とディクショナリで関連付けられていたものを、”apple”は4個、と値を更新したい、ということになります。
それに対して、実装は fruits.Add(“apple”, 4); となっており、値の更新、という目的とは異なる処理が記述されています。
このような場合、修正方法は以下のようにすると良いでしょう。
fruits["apple"] = 4;
上記の書き方は、キー”apple”が無い場合はキーの追加と値の設定を同時に行います。また、すでにキー”apple”が存在してる場合は、そのキーに対応する値のみ更新することができます。
ディクショナリ fruits がフルーツごとにユニークなIDを与える目的の場合
このケースでは、ディクショナリ fruits にはフルーツの名前が沢山入力され、その名前ごとに異なるIDを設定していきます。
このとき、既に登録済みの “apple” であれば、登録を行なわず無視したいはずです。それに対し、実際の処理は、無条件に “apple” を登録しようとしています。
このような場合、修正方法は以下のようにすると良いでしょう。
if( !fruits.ContainsKey( "apple" ) ){ // "apple" が登録済みの場合は無視
fruits[ "apple" ] = 4;
}
上記の書き方は、キー”apple”が既に登録されている場合は、キーの追加と値の設定を行いません。
まとめ
本記事では、ディクショナリを使用した処理で発生するエラー「同一のキーを含む項目が既に追加されています。」の対処方法について紹介しました。
エラーが発生した場合は、単純にそのエラー発生を抑え込むのではなく、まずはエラー発生の原因やソフトの設計を考慮し、修正の方針を決めましょう。