基本的に、私はこのようなものが欲しいです:
Dictionary<object, string> dict = new Dictionary<object, string>();
dict.Add(null, "Nothing");
dict.Add(1, "One");
これを可能にする基本クラスライブラリに組み込まれているものはありますか?上記のコードは、nullキーを追加すると、実行時に例外をスローします。
基本的に、私はこのようなものが欲しいです:
Dictionary<object, string> dict = new Dictionary<object, string>();
dict.Add(null, "Nothing");
dict.Add(1, "One");
これを可能にする基本クラスライブラリに組み込まれているものはありますか?上記のコードは、nullキーを追加すると、実行時に例外をスローします。
nullの使用を避けて、同じことを行う特別なシングルトン値クラスを作成することができます。例えば:
public sealed class Nothing
{
public static readonly Nothing Value = new Nothing();
private Nothing() {}
}
Dictionary<object, string> dict = new Dictionary<object, string>();
dict.add(Nothing.Value, "Nothing");
dict.add(1, "One");
コレクションをより強く型付けする場合、このアプローチは機能しません。たとえば、キーを文字列にしたい場合などです。文字列は封印されているため、文字列から継承してnullの代わりに「特別な値」を作成することはできません。あなたの選択肢はもう少し複雑になります。あなたは出来る:
余談ですが、辞書のキーには本当にキーが必要object
ですか?これにより、Equals()を比較の基礎として評価することを意図した場合に、参照の同等性が使用されるため、微妙なバグが発生する可能性があります。
これはどう?
public class NullableDictionnary<T1, T2> : Dictionary<T1, T2>
{
T2 null_value;
public T2 this[T1 key]
{
get
{
if (key == null)
{ return null_value; }
return base[key];
}
set
{
if (key == null)
{ null_value = value; }
else
{ base[key] = value; }
}
}
}
NameValueCollectionはnullキーを取ることができますが、IDictionaryを実装していません。ただし、DictionaryBaseから派生して、nullを次のような組み込みのものに置き換えるだけのAdd / Remove/Indexersなどを提供するのは非常に簡単です。
class MyDictionary : DictionaryBase {
private readonly object nullKey = new object();
void Add(object key, string value) {
if ( key == null ) { key = nullKey; }
.. call base methods
}
}
辞書の別の実装は必要ありません。
ここで私の答えを見てください: https ://stackoverflow.com/a/22261282/212272
辞書を強く入力したままにすることもできます。
var dict = new Dictionary<NullObject<int?>, string>();
dict[1] = "one int";
dict[null] = "null int";
Assert.AreEqual("one int", dict[1]);
Assert.AreEqual("null int", dict[null]);
キーは文字通りNULLである必要がありますか?コレクションのキーはインデックスとして機能します。コレクション内のインデックスにNULLを設定することは、私にはあまり意味がありません。
たぶん、新しいクラスを作成します
public class ObjectEntry
{
public object objRef;
public string desc;
public ObjectEntry(object objectReference)
{
objRef = objectReference;
if (objRef = null) {desc = "Nothing";}
else {desc = objRef.Description;} //or whatever info you can get from a proper objRef value
}
}
newObj = new ObjectEntry(null);
dict.add(newObj, newObj.desc);
たとえば、ValueTupleをキーのラッパーとして使用できます。
Dictionary<ValueTuple<string?>, string>
あなたがやろうとしていることをより明確にする、よりクリーンな(私にとって)解決策を作るためのjestroの答えのわずかなバリエーション。明らかに、これは必要に応じて拡張できます。しかし、あなたは絵を手に入れます、ただラッパーを作ってください。
public class NullDictionary<TKey, TValue> : Dictionary<TKey, TValue>
{
private TValue _default;
public new TValue this[TKey key]
{
get {
if(key == null)
{
return _default;
}
return _decorated[key];
}
}
private Dictionary<TKey, TValue> _decorated;
public NullDictionary( Dictionary<TKey,TValue> decorate, TValue defaultValue = default)
{
_decorated = decorate;
_default = defaultValue;
}
}