ASystem.Collections.Generic.Dictionary
がスローKeyNotFoundException
されていますが、どのキーが欠落しているのかわかりません。これをどのように判断しますか?
7 に答える
例外からこれを伝える方法はありません。これには独自のソリューションを実装する必要があります。
ディクショナリが宣言されている実装をカスタマイズできる場合は、System.Collections.Generic.Dictionary をより適切な KeyNotFoundException をスローするカスタム型に簡単に置き換えることができます。これは abatishchev の答えに似ていますが、彼が導入した拡張メソッドは好きではありません。まったく同じことを達成するために 2 つの異なる方法があることを意味するからです。これは、可能であれば避けるべきです。代わりに「NiceDictionary」を使用して問題を解決しました。これは、基本クラスとして使用される元の Dictinary とまったく同じように使用できます。実装はほとんど簡単です:
/// <summary>
/// This is a nice variant of the KeyNotFoundException. The original version
/// is very mean, because it refuses to tell us which key was responsible
/// for raising the exception.
/// </summary>
public class NiceKeyNotFoundException<TKey> : KeyNotFoundException
{
public TKey Key { get; private set; }
public NiceKeyNotFoundException(TKey key, string message)
: base(message, null)
{
this.Key = key;
}
public NiceKeyNotFoundException(TKey key, string message, Exception innerException)
: base(message, innerException)
{
this.Key = key;
}
}
/// <summary>
/// This is a very nice dictionary, because it throws a NiceKeyNotFoundException that
/// tells us the key that was not found. Thank you, nice dictionary!
/// </summary>
public class NiceDictionary<TKey, TVal> : Dictionary<TKey, TVal>
{
public new TVal this[TKey key]
{
get
{
try
{
return base[key];
}
catch (KeyNotFoundException knfe)
{
throw new NiceKeyNotFoundException<TKey>(key, knfe.Message, knfe.InnerException);
}
}
set
{
try
{
base[key] = value;
}
catch (KeyNotFoundException knfe)
{
throw new NiceKeyNotFoundException<TKey>(key, knfe.Message, knfe.InnerException);
}
}
}
}
前述のように、元の辞書を使用するのと同じように使用できます。オーバーライドされた配列演算子 ([]) により、魔法のように機能します。
例外を見るだけではできません。例外がスローされたときにデバッガーに割り込む必要があります ( Visual Studio で[デバッグ] -> [例外 ] を選択)、どのキーがアクセスされたかを確認します。別の方法として、コードで例外をキャッチし、それを (コンソールなどに) 表示することもできます。
デバッガーを使用して (必要に応じて、Debug->Exceptions の ThrowOnCatch をチェックしてください)、見てください。