40

KeyValuePair<T,U>aに aを追加したかったのですが、Dictionary<T, U>できませんでした。キーと値を別々に渡す必要があります。これは、Add メソッドが挿入する新しい KeyValuePair オブジェクトを作成する必要があることを意味し、あまり効率的ではありません。Add(KeyValuePair<T, U>)Add メソッドにオーバーロードがないなんて信じられません。この明らかな見落としの考えられる理由を誰か提案できますか?

4

8 に答える 8

42

メソッドIDictionary<TKey,TValue>を提供するインターフェースを使用できます。Add(KeyValuePair<TKey,TValue>)

IDictionary<int, string> dictionary = new Dictionary<int, string>();
dictionary.Add(new KeyValuePair<int,string>(0,"0"));
dictionary.Add(new KeyValuePair<int,string>(1,"1"));
于 2012-10-22T13:19:30.753 に答える
39

少しバックアップしてください...見落としの道を進む前に、新しい KeyValuePair の作成が本当に非効率的であるかどうかを確認する必要があります。

まず、Dictionary クラスはキーと値のペアのセットとして内部的に実装されているのではなく、一連の配列として実装されています。それはさておき、それが単なる KeyValuePairs のセットであると仮定して、効率を見てみましょう。

最初に気付くのは、KeyValuePairが構造体であることです。つまり、メソッド パラメーターとして渡すには、スタックからヒープにコピーする必要があります。KeyValuePair がディクショナリに追加されると、値の型のセマンティクスを保証するためにもう一度コピーする必要があります。

キーと値をパラメーターとして渡すために、各パラメーターは値型または参照型のいずれかになります。それらが値型である場合、パフォーマンスは KeyValuePair ルートと非常に似ています。それらが参照型である場合、これは実際にはより高速な実装になる可能性があります。これは、アドレスのみを渡す必要があり、コピーをほとんど実行する必要がないためです。最良のケースと最悪のケースの両方で、KeyValuePair 構造体自体のオーバーヘッドが増加するため、このオプションは KeyValuePair オプションよりわずかに優れています。

于 2012-10-22T13:24:21.220 に答える
18

そのようなメソッドはありますICollection<KeyValuePair<K, T>>.Addが、明示的に実装されているため、辞書オブジェクトをそのインターフェイスにキャストしてアクセスする必要があります。

((ICollection<KeyValuePair<KeyType, ValueType>>)myDict).Add(myPair);

見る

このメソッドのページには例が含まれています。

于 2012-10-22T13:19:59.150 に答える
2

私が間違っていない限り、.NET 4.5 および 4.6 では、KeyValuePair を Dictionary に追加する機能が追加されています。(私が間違っている場合は、私に通知してください。この回答を削除します。)

https://msdn.microsoft.com/en-us/library/cc673027%28v=vs.110%29.aspx

上記のリンクから、関連する情報は次のコード例です。

public static void Main() 
{
    // Create a new dictionary of strings, with string keys, and 
    // access it through the generic ICollection interface. The 
    // generic ICollection interface views the dictionary as a 
    // collection of KeyValuePair objects with the same type 
    // arguments as the dictionary. 
    //
    ICollection<KeyValuePair<String, String>> openWith =
        new Dictionary<String, String>();

    // Add some elements to the dictionary. When elements are  
    // added through the ICollection<T> interface, the keys 
    // and values must be wrapped in KeyValuePair objects. 
    //
    openWith.Add(new KeyValuePair<String,String>("txt", "notepad.exe"));
    openWith.Add(new KeyValuePair<String,String>("bmp", "paint.exe"));
    openWith.Add(new KeyValuePair<String,String>("dib", "paint.exe"));
    openWith.Add(new KeyValuePair<String,String>("rtf", "wordpad.exe"));

    ...
}

ご覧のとおり、Dictionary 型の新しいオブジェクトが作成され、呼び出されopenWithます。次に、新しい KVP オブジェクトが作成され、メソッドをopenWith使用して に追加されます。.Add

于 2015-06-29T21:23:26.273 に答える
2

誰かが本当にこれをやりたいなら、ここに拡張機能があります

    public static void Add<T, U>(this IDictionary<T, U> dic, KeyValuePair<T, U> KVP)
    {
        dic.Add(KVP.Key, KVP.Value);
    }

しかし、これを行う必要がない場合は、これを行わないことをお勧めします

于 2013-11-05T11:09:42.247 に答える
1

Dictionary クラスの列挙子が KeyValuePair を返すからといって、内部的に実装されているわけではありません。

すでに KVP をその形式で取得しているため、本当に KVP を渡す必要がある場合は IDictionary を使用してください。それ以外の場合は、代入を使用するか、単に Add メソッドを使用してください。

于 2012-10-22T13:26:11.517 に答える
-2

100% 確実ではありませんが、ディクショナリの内部実装はハッシュ テーブルであると思います。これは、キーがハッシュに変換されてクイック ルックアップを実行することを意味します。

ハッシュテーブルについて詳しく知りたい場合は、こちらをお読みください

http://en.wikipedia.org/wiki/Hash_table

于 2012-10-22T13:22:40.677 に答える