4
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Dictionaryを二度検索しないようにする

Posted at

参考

この記事は、以下の動画を参考にしています。
詳しくは、動画をご覧ください。

状況

public static TValue GetOrAdd<TKey, TValue>(
    this Dictionary<TKey, TValue> dict, TKey key, TValue value)
    where TKey : notnull
{
    if (dict.TryGetValue(key, out var result)) // 辞書内を検索
        return result;

    dict[key] = value; // ここでも辞書内を検索
    return value;
}
  1. 辞書に、指定したキーに対応するエントリーあれば、その値を戻す
  2. キーに対応するエントリーがなければ、指定した値でキーに対応するエントリーを作り、その値を戻す

というメソッド。

このとき、1. と 2. の2回、辞書内の検索が実行されてしまう。

これを、1回の検索で済むようにできないものか。

解決法

public static TValue GetOrAdd<TKey, TValue>(
    this Dictionary<TKey, TValue> dict, TKey key, TValue value)
    where TKey : notnull
{
    ref var val = ref CollectionsMarshal.GetValueRefOrAddDefault(dict, key, out var exists);
    if (exists)
    {
        return val;
    }

    val = value; // 単なる代入
    return value;
}

System.Runtime.InteropServices.CollectionsMarshalクラスのGetValueRefOrAddDefaultメソッドを使う。(.NET 9から)

CollectionsMarshal.GetValueRefOrAddDefaultメソッドが、

  1. 辞書に、指定したキーに対応するエントリーあれば、その参照を戻す
  2. キーに対応するエントリーがなければ、エントリーを作り、その参照を戻す

まで行ってくれる。

これで、辞書を二度検索する必要がなくなる。

他にも

CollectionsMarshal.GetValueRefOrNullRefメソッドでは、キーに対応するエントリーがなかった場合、null参照を戻す。

4
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?