必要な拡張メソッドは 1 つだけです。次のように再定義します。
public static TValue? GetNullableKey<TKey, TValue>(this IEnumerable<KeyValuePair<TKey, TValue>> dictionary, TKey, key) where TValue : struct
{
// Your code here.
// Per @nmclean: to reap performance benefits of dictionary lookup, try to cast
// dictionary to the expected dictionary type, e.g. IDictionary<K, V> or
// IReadOnlyDictionary<K, V>. Thanks for that nmclean!
}
との両方がIDictionary<TKey, TValue>
からIReadOnlyDictionary<TKey, TValue>
継承されIEnumerable<KeyValuePair<TKey, TValue>>
ます。
HTH。
更新:コメントの質問に答えるには
いずれかのインターフェイスにのみ表示されるメソッドを呼び出す必要がない場合 (つまり、 に存在するメソッドのみを呼び出す場合IEnumerable<KeyValuePair<TKey, TValue>>
)、いいえ、そのコードは必要ありません。
IDictionary<TKey, TValue>
共通の基本インターフェースに存在しないまたはインターフェースのいずれかでメソッドを呼び出す必要がある場合はIReadOnlyDictionary<TKey, TValue>
、はい、どのメソッドが呼び出されるのに有効かを知るために、オブジェクトがどちらであるかを確認する必要があります。
更新:おそらく(ほとんどの場合)このソリューションを使用しないでください
したがって、技術的には、このソリューションは OP の質問に答える上で正しいと述べられています。ただし、他の人が以下にコメントしているように、これは本当に良い考えではありません.
1 つには、ディクショナリ/マップの要点は O(1) (一定時間) ルックアップです。上記のソリューションを使用して、O(1) 操作を O(n) (線形時間) 操作に変換しました。ディクショナリに 1,000,000 項目ある場合、キー値を検索するのに最大で 100 万倍の時間がかかります (本当に運が悪い場合)。これは、パフォーマンスに重大な影響を与える可能性があります。
小さな辞書はどうですか?さて、質問は、本当に辞書が必要ですか? リストにしたほうがいいですか?または、さらに良い質問: O(1) ルックアップに対して O(n) を使用することのパフォーマンスへの影響にどこから気付き始めますか? また、そのようなルックアップを実行する頻度はどれくらいになると予想されますか?
最後に、 の動作が の動作のスーパーセットであるため、と の両方 IReadOnlyDictionary<TKey, TValue>
を実装するオブジェクトを使用した OP の状況IDictionary<TKey, TValue>
は、奇妙です。そして、標準クラスはすでにこれらのインターフェースの両方を実装しています。したがって、OP の (特殊化されていると思います) 型が代わりに継承された場合、読み取り専用機能が必要な場合、型は単純に にキャストされ、おそらくこの問題全体を完全に回避できます。問題が避けられない場合でも (たとえば、どこかでインターフェイスの 1 つにキャストが行われるなど)、インターフェイスごとに 1 つずつ、2 つの拡張メソッドを実装したほうがよいでしょう。IDictionary<TKey, TValue>
IReadOnlyDictionary<TKey, TValue>
Dictionary<TKey, TValue>
Dictionary<TKey, TValue>
IReadOnlyDictionary<TKey, TValue>
このトピックを終了する前に、もう 1 つ注文する必要があると思います。a を to にキャストするDictionary<TKey, TValue>
とIReadOnlyDictionary<TKey, TValue>
、キャストされた値を受け取るもの自体が基になるコレクションを変更できないことが保証されるだけです。ただし、キャストされた参照の作成元のディクショナリ インスタンスへの他の参照が、基になるコレクションを変更しないという意味ではありません。IReadOnly*
これは、コレクション インターフェイスの背後にある問題の 1 つです。これらのインターフェイスによって参照されるコレクションは、真の意味で「読み取り専用」(または、しばしば暗に示される不変) コレクションではない可能性があり、特定の参照によるコレクションの変更を防止するだけです (にもかかわらず、具体的なReadOnly*
クラスの実際のインスタンス)。これが (とりわけ) 理由の 1 つです。System.Collections.Immutable
コレクション クラスの名前空間が作成されました。この名前空間のコレクションは、真に不変のコレクションを表しています。これらのコレクションの「変異」により、変異した状態で構成されるまったく新しいコレクションが返され、元のコレクションは影響を受けません。