このスレッドでは
キーでディクショナリ値にアクセスする KeyNotFoundException の代わりに null を取得する方法は?
私自身の答えでは、明示的なインターフェイス実装を使用してKeyNotFoundException
、キーが辞書に存在しない場合にスローしない基本的な辞書インデクサーの動作を変更しました(null
そのような場合、インラインで取得するのが便利だったため)。
ここにあります:
public interface INullValueDictionary<T, U>
where U : class
{
U this[T key] { get; }
}
public class NullValueDictionary<T, U> : Dictionary<T, U>, INullValueDictionary<T, U>
where U : class
{
U INullValueDictionary<T, U>.this[T key]
{
get
{
if (ContainsKey(key))
return this[key];
else
return null;
}
}
}
実際のアプリケーションでは辞書のリストがあったため、インターフェイスとしてコレクションから辞書にアクセスする方法が必要でした。リストの各要素にアクセスするために単純なint
インデクサーを使用しました。
var list = new List<NullValueDictionary<string, string>>();
int index = 0;
//...
list[index]["somekey"] = "somevalue";
最も簡単なことは、次のようなことをすることでした:
var idict = (INullValueDictionary<string, string>)list[index];
string value = idict["somekey"];
共分散機能を使用して、代わりに使用するインターフェイスのコレクションを使用しようと決めたときに発生した質問。そのため、キャストを機能させるには、共変型パラメーターを持つインターフェイスが必要でした。最初に頭に浮かんだのは だったIEnumerable<T>
ので、コードは次のようになります。
IEnumerable<INullValueDictionary<string, string>> ilist = list;
string value = ilist.ElementAt(index)["somekey"];
ElementAt
インデクサーの代わりに、はるかに悪いことに加えて、それほど良いことではありません。のインデクサーList<T>
は で定義されておりIList<T>
、T
共変ではありません。
私は何をすべきでしたか?私は自分で書くことにしました:
public interface IIndexedEnumerable<out T>
{
T this[int index] { get; }
}
public class ExtendedList<T> : List<T>, IIndexedEnumerable<T>
{
}
まあ、数行のコード (私は何も書く必要さえありませんExtendedList<T>
)、そしてそれは私が望んでいたように動作します:
var elist = new ExtendedList<NullValueDictionary<string, string>>();
IIndexedEnumerable<INullValueDictionary<string, string>> ielist = elist;
int index = 0;
//...
elist[index]["somekey"] = "somevalue";
string value = ielist[index]["somekey"];
最後に、追加のコレクションを作成せずに、この共変キャストを何らかの形で実現できるかという問題があります。