【ITニュース解説】【C#/Unity】Dictionaryに値を追加すると発生する 「ArgumentException: An item with the same key has already been adde」の原因と解決法
2025年09月06日に「Qiita」が公開したITニュース「【C#/Unity】Dictionaryに値を追加すると発生する 「ArgumentException: An item with the same key has already been adde」の原因と解決法」について初心者にもわかりやすく解説しています。
ITニュース概要
C#やUnityでDictionaryを使う際、「ArgumentException: An item with the same key has already been added.」エラーは、同じ名前(キー)で既に登録されているデータを再度追加しようとすると発生する。追加前にキーの有無を確認し、重複を避けるのが解決策だ。
ITニュース解説
Dictionaryとは、プログラムの中でデータを整理するための非常に便利なデータ構造の一つである。一般的な配列やリストが、0番目、1番目、2番目といった連番の数値(インデックス)を使ってデータを取り出すのに対し、Dictionaryは「キー」と呼ばれる特定の名前や識別子を使ってデータを取り出す。例えば、「player1」というキーには「田中」、「player2」というキーには「佐藤」といったように、キーと値のペアでデータを管理する。このような形式は、大量のデータの中から特定の情報を素早く見つけ出したり、柔軟にデータを追加・更新したりする際に非常に強力なツールとなるため、ゲーム開発でキャラクターの情報、アイテムのデータ、設定値などを管理する際によく利用される。
しかし、この便利なDictionaryを利用していると、「ArgumentException: An item with the same key has already been added. Key: player1」というエラーメッセージに遭遇することがある。このエラーメッセージは、「同じキーを持つ項目が既に追加されています。キー: player1」という意味であり、具体的には「player1」というキーが既にDictionaryの中に存在しているにもかかわらず、もう一度「player1」というキーを使って新しいデータを追加しようとした際に発生する問題を示している。
このエラーが発生する根本的な原因は、C#のDictionaryが持つ重要な特性、すなわち「キーは常に一意でなければならない」という規則にある。Dictionaryは、特定のキーに対応する値を効率的に見つけ出すことを目的としているため、もし同じキーが複数存在してしまうと、どの値を取り出せばよいのかを正確に判断できなくなってしまう。このような状況を防ぎ、データの整合性を保つために、Dictionaryは既に存在するキーと同じキーで新たな項目を追加しようとすると、このArgumentExceptionを発生させて処理を中断させる仕組みになっている。
この問題を解決する方法はいくつか存在する。まず、最も基本的な解決策は、Dictionaryに値を追加する前に、目的のキーが既に存在するかどうかを確認することである。これには、Dictionaryが提供するContainsKeyメソッドが非常に役立つ。ContainsKeyメソッドは、引数で渡されたキーがDictionary内に存在すればtrueを、存在しなければfalseを返す。したがって、プログラムはContainsKeyメソッドを使ってキーの存在を確認し、もしキーが存在しない場合にのみ、Addメソッドを使って新しいキーと値のペアを追加するように記述すれば、エラーの発生を確実に防ぐことができる。例えば、「もし"player1"というキーがDictionaryにまだ存在しないなら、"player1"をキーとして"田中"を値とするデータを追加する」という条件を設けることで、二重の追加を回避する。
次に、キーが存在する場合に値を更新したい、というケースもよく発生する。この場合もContainsKeyでキーの存在を確認した後に処理を分岐させる。もしキーが存在すれば、Dictionaryのインデクサ([])を使ってそのキーに対応する値を直接更新する。例えば、「myDictionary["player1"] = "新しい名前";」のように記述することで、既存の「player1」というキーに対応する値が「田中」から「新しい名前」に上書きされる。一方、キーが存在しない場合は、Addメソッドで新しいキーと値のペアを追加する。これにより、キーの存在有無に応じて追加と更新を適切に使い分けることが可能となる。
さらにコードを簡潔に記述する方法として、C# 7.0以降で導入されたTryAddメソッドを使用する方法がある。TryAddメソッドは、キーと値のペアをDictionaryに追加しようと試み、もしそのキーが既に存在しなかった場合にのみ追加に成功しtrueを返す。もしキーが既に存在していた場合は、追加を試みずにfalseを返す。このメソッドは、キーの存在確認と追加処理を一度に行えるため、コードをよりシンプルかつ効率的に記述できる利点がある。
また、Dictionaryのインデクサ([])は、Addメソッドとは異なる挙動をする点に注意が必要である。Addメソッドは、キーが既に存在すると必ずエラーを発生させるが、インデクサ[]を使って値を設定しようとした場合、指定したキーがDictionary内に存在しなければそのキーと値を追加し、もし既に存在していれば既存のキーに対応する値を更新するという挙動をする。つまり、「myDictionary["player1"] = "値";」という記述は、キー「player1」が存在しない場合は新しい項目として追加され、既に存在する場合はそのキーに対応する値が更新されるという、非常に便利な機能を提供する。この特性を理解し、目的の処理(新しい項目を確実に追加したいのか、それとも既存項目を上書きしても問題ないのか)に応じてAddメソッドを使うか、インデクサ[]を使うかを適切に選択することが重要となる。
これらの解決策を適切に適用することで、Dictionary使用時に発生する「ArgumentException: An item with the same key has already been added.」というエラーを回避し、安定したデータ管理を実現できる。Unityのようなゲーム開発環境では、プレイヤーのステータス、ゲームの設定、インベントリ内のアイテムリストなど、多種多様な情報をDictionaryで管理する機会が非常に多いため、このエラーの発生原因とその解決法を理解しておくことは、システムエンジニアを目指す上で極めて重要である。Dictionaryのキーは一意であるという基本的なルールを常に意識し、データを追加する際にはキーの存在を適切にチェックする習慣を身につけることが、バグの少ない堅牢なプログラムを作成する上で不可欠なスキルとなる。