は私がクリーナーコードは次のようになります言うと思います:
var key = arr[i];
var hasKey = dictionary.ContainsKey(key);
if (!hasKey)
dictionary.Add(key, new A());
var itemToUse = dictionary[key];
itemToUse.Push(10);
それは私には思えるが、あなたが何か短いを探しています。私はあなたが本当に求めているのはショートハンドメソッドです:
キーが存在する場合は指定されたキーの値を返し、そうでない場合はデフォルト値で辞書にキーを追加します。
私は上記のコードが意図について多くのことを教えてくれると思いますが、あなたが何か違うものを求めたい場合は、次の2つの解決策を考えることができます。
最初のものは、アイテムを取得するための拡張メソッドです:
public static TValue Get<TKey, TValue>(this Dictionary<TKey, TValue> dictionary, TKey key, TValue defaultValue)
{
var hasKey = dictionary.ContainsKey(key);
if (!hasKey)
dictionary.Add(key, defaultValue);
return dictionary[key];
}
としてあなたはそれを使用します。私は考えることができる第二の溶液は、辞書の新しい誘導体である
dict.Get(arr[i], defaultValue: new A())
.Push(10);
:
:
class DefaultDictionary<TKey, TValue> : Dictionary<TKey, TValue>
{
private readonly Func<TKey, TValue> _defaultValueFactory;
public DefaultDictionary(TValue defaultValue)
{
_defaultValueFactory = new Func<TKey, TValue>(x => defaultValue);
}
public DefaultDictionary(Func<TValue> defaultValueFactory)
{
_defaultValueFactory = new Func<TKey, TValue>(x => defaultValueFactory()) ?? throw new ArgumentNullException(nameof(defaultValueFactory));
}
public DefaultDictionary(Func<TKey, TValue> defaultValueFactory)
{
_defaultValueFactory = defaultValueFactory ?? throw new ArgumentNullException(nameof(defaultValueFactory));
}
public new TValue this[TKey key]
{
get
{
var hasKey = ContainsKey(key);
if (!hasKey)
{
var defaultValue = _defaultValueFactory(key);
Add(key, defaultValue);
}
return base[key];
}
set
{
base[key] = value;
}
}
}
これの使い方は次のようになります
var dictionary = new DefaultDictionary<string, A>(() => new A());
// ...
dictionary[arr[i]].Push(10);
私は何かについて警告する必要があります。このDictionaryの派生語は、インデックス演算子を隠します。また、メンバの型としてIDictionaryを使用するのが一般的です(たとえば、private IDictionary<string, A> dictionary
をメンバとして使用)ので、キャストせずにオーバーロードされたバージョンを使用することはできません。だから、DefaultDictionaryにあなたがオーバーロードされたインデクサーを使用するたびに、あなたの変数をキャストのいずれか、または同様に、この新しい辞書のためのインタフェースを持っている:
:
interface IDefaultDictionary<TKey, TValue> : IDictionary<TKey, TValue>
{
new TValue this[TKey key] { get; set; }
}
そして、あなたのメンバーを持っている、変数は、その定義型としてそれを使用します
private IDefaultDictionary<string, A> dictionary;
しかし、これは具体的なクラスとしてDefaultDictionaryを使用する必要があります。これはトレードオフです。
'dictionary [i] = dictionary [i]'? – JohnyL
完全なコード(少なくともメソッド - 一部ではない)を表示し、ここにも望ましい出力を表示するとよいでしょう。それ以外の場合は、あなたが望むものは明確ではありません。 – Vladimir
[.NETディクショナリ:get or create new](https://stackoverflow.com/questions/16192906/net-dictionary-get-or-create-new) – Rotem