【C#】System.ArgumentException: ‘同一のキーを含む項目が既に追加されています。’

C#

このエラー(例外)は、ディクショナリに対して、同一のキーを再度追加しようとした場合に発生します。

サンプルコード

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”が既に登録されている場合は、キーの追加と値の設定を行いません。

まとめ

エラー(例外)が発生した場合、単純にそのエラー発生を抑え込むのではなく、まずはエラー発生の原因やソフトの設計を考慮し、修正の方針を決めましょう。

タイトルとURLをコピーしました