ホームページ  >  記事  >  バックエンド開発  >  C# コレクション型のグラフィック コードの詳細な説明

C# コレクション型のグラフィック コードの詳細な説明

黄舟
黄舟オリジナル
2017-03-09 15:23:191985ブラウズ

C# のコレクション

コレクションは .NET FCL (フレームワーク クラス ライブラリ) の重要な部分であり、開発で最も一般的に使用される関数の 1 つです。よく言われるように、IEnumerable、IEnumerator、および ICollection を見たとき、それが何なのか、そしてなぜそうなるのかを理解してください。それらの違いがわかりますか? List と Dictionary 以外に、他にどのようなコレクション クラスを使用したことがありますか?さっそく、今日はコレクション クラスとその実装を定義するインターフェイスのいくつかを見てみましょう。

コレクションインターフェース

まず、FCL が提供するインターフェイスを見てみましょう:

IEnumerable と IEnumberator

public interface IEnumerator
{
 
    bool MoveNext();
    object Current {  get; }
    void Reset();
}

IEnumerator は、コレクション内の各要素への一方向の前方アクセスを実現できるように、コレクションを走査するための基本的なメソッドを定義します。 IEnumerable には、トラバーサーである GetEnumerator というメソッドが 1 つだけあります。

りー

注: 私たちがよく使用する foreach は、実際には Enumerator の Current と MoveNext によって実装されたトラバーサル関数を呼び出します。

りー

上記のコードで使用されている foreach と列挙子は、最終的に IL の列挙子の MoveNext と Current に変換されます。

IEnumerable は非常に便利なインターフェイスです。実装すると次のような利点があります。 foreach ステートメントをサポート


  1. 標準のコレクション クラスとして他のライブラリと対話します


  2. より複雑なコレクションインターフェイスのニーズを満たす


  3. コレクション初期化子をサポートします

  4. もちろん、それを達成するには次のようにさまざまな方法があります:

コレクションが他のコレクション クラスをカプセル化することによって取得される場合、このコレクションの列挙子を直接返すことができます


  1. イールドリターンを通じてリターン


  2. 独自の IEnumerator を実装して

  3. を実現します ここでは、yield を通じて列挙子を返す方法を説明します

    public interface IEnumerable
    {
        IEnumerator GetEnumerator();
    }
  4. ICollection8742468051c85b06f0a0af9e3e506b5c と ICollection

上部の最初の図から、ICollection が IEnumerable から直接継承されていることがわかります。実際、これも当てはまります。ICollection は、基本的なトラバーサル関数を提供するだけでなく、次の機能もサポートしていると言えます。 セットと要素の数を数えます

  1. 要素の添字を取得します


  2. があるかどうかを判断します 最後に要素を追加します

  3. 要素などを削除します。 。 。

  4. ICollection は ICollection8742468051c85b06f0a0af9e3e506b5c とは少し異なります。ICollection にはコレクションの編集機能、つまり追加と削除がありません。要素が存在するかどうかのチェックを含める Contains はサポートされていません。

  5. IList8742468051c85b06f0a0af9e3e506b5c と IList
  6. IList は ICollection と IEnumerable を直接継承します。したがって、両方の機能が含まれており、添字に基づいた要素へのアクセスと追加がサポートされています。 IndexOf、Insert、RemoveAt など。 IEnumerable は、トラバーサルのみをサポートする最小限の機能をサポートしていると言えます。 ICollection は、コレクションの走査だけでなく維持など、もう少し多くの機能をサポートします。 IList は最も完全なバージョンです。

    IReadOnlyList8742468051c85b06f0a0af9e3e506b5c
これは Framework 4.5 の新しいインターフェイス タイプであり、このコレクションを変更する可能性のあるすべての関数を削除した IList8742468051c85b06f0a0af9e3e506b5c の短縮バージョンとみなすことができます。例: Add、RemoveAt など。

IDictionary

IDictionary は、キーと値のペアのコレクションへのアクセスを提供し、ICollection8742468051c85b06f0a0af9e3e506b5c と IEnumerable を継承し、Key を介してデータにアクセスして操作する方法を拡張します。

連想ジェネリックコレクションクラス

連想コレクション クラスは、キーと値のペアのコレクションとよく呼ばれるもので、キーを介してコレクションにアクセスし、維持できるようにします。まず、FCL が提供する汎用連想コレクション クラスを見てみましょう:

辞書8c189faf63255a5ea96468ba21dd0564

  1. SortedDictionary8c189faf63255a5ea96468ba21dd0564


  2. ソートされたリスト

辞書

Dictionary8c189faf63255a5ea96468ba21dd0564 は、おそらく最も一般的に使用される連想コレクションであり、データのアクセス、追加、削除にかかる時間は、ストレージ構造として内部的に Hashtable を使用するため、すべてのコレクション クラスの中で最も高速です。保存されるキーと値のペアの数、クエリ/追加/削除にかかる時間は同じで、時間計算量は O(1) です。

Dictionary8c189faf63255a5ea96468ba21dd0564利点は検索と挿入が速いことですが、欠点は何ですか? Hashtable がストレージ構造として使用されているため、内部のデータは順序付けされていないため、Dictionary 内のデータを特定の順序で走査するのに少し手間がかかります。

TKey タイプとして、GetHashCode()Equals() を実装するか、IEqualityComparer を提供する必要があります。そうしないと、操作に問題が発生する可能性があります。

並べ替えられた辞書8c189faf63255a5ea96468ba21dd0564

SortedDictionary8c189faf63255a5ea96468ba21dd0564 と Dictionary8c189faf63255a5ea96468ba21dd0564 はほぼ似ていますが、実装には若干の違いがあります。 SortedDictionary8c189faf63255a5ea96468ba21dd0564 は、ストレージ構造としてバイナリ ツリーを使用します。そしてキー順に並べました。この場合、SortedDictionary の TKey は

IComparable を実装する必要があります。 クエリをすばやく実行し、並べ替えを適切にサポートしたい場合は、SortedDictionary を使用します。

ソートリスト8c189faf63255a5ea96468ba21dd0564

SortedList8c189faf63255a5ea96468ba21dd0564 は、並べ替えをサポートするもう 1 つの連想コレクションです。ただし、SortedList が実際にデータを配列に格納する点が異なります。つまり、要素の操作によりすべてのデータが移動する可能性があるため、追加操作と削除操作は線形であり、時間計算量は O(n) です。ただし、検索中に二分検索が使用されるため、検索パフォーマンスは向上し、時間計算量は O(log n) になります。したがって、推奨される使用シナリオは次のとおりです。 高速に検索したい、コレクションをキー順に並べたい、コレクションの操作 (追加と削除) が比較的少ない場合は、SortedList です。

非連想ジェネリックコレクションクラス

非連想コレクションは、キー操作を必要としないコレクション クラスで、通常は要素自体または添字を使用して操作できます。 FCL は主に次の非連想ジェネリック コレクション クラスを提供します。

  1. リスト8742468051c85b06f0a0af9e3e506b5c


  2. リンクリスト8742468051c85b06f0a0af9e3e506b5c


  3. ハッシュセット8742468051c85b06f0a0af9e3e506b5c


  4. ソートセット8742468051c85b06f0a0af9e3e506b5c


  5. スタック8742468051c85b06f0a0af9e3e506b5c


  6. キュー8742468051c85b06f0a0af9e3e506b5c

リスト8742468051c85b06f0a0af9e3e506b5c

ジェネリック List クラスは、長さに制限のないコレクション型を提供します。List は、内部的に一定の長さの配列を保持します (デフォルトの初期長は 4 です)。挿入された要素の長さが 4 または初期長を超えると、その配列が返されます。 -作成された新しい配列。この新しい配列の長さは初期の長さの 2 倍 (必ずしも 2 倍ではなく、拡張が続くことが判明した場合は倍数が大きくなります) にして、元の配列をコピーします。したがって、このコレクションを使用して保持する要素の数がわかっていれば、コレクションを作成するときに初期値を指定できるため、新しい配列の作成と値のコピーを繰り返す必要がなくなります。

また、内部の本質は配列であるため、List へのデータの追加は高速ではありませんが、データの先頭や途中にデータを追加または削除すると、他のデータの並べ替えに影響を与えるため、比較的効率が悪くなります。

リンクリスト8742468051c85b06f0a0af9e3e506b5c

LinkedList は内部的に双方向のリンク リストを維持します。これは、LinkedList 内の任意の場所でデータを追加または削除するパフォーマンスが非常に高速であることを意味します。他の要素を動かさないからです。通常の状況では List で十分ですが、このコレクションの途中で追加および削除操作が頻繁に行われる場合は、LinkedList を使用することをお勧めします。

ハッシュセット8742468051c85b06f0a0af9e3e506b5c

HashSet は、一意性を維持できる順序のないセットです。 TKey と TValue の両方が同じオブジェクトを指す点を除いて、HashSet を Dictionary と考えることもできます。 HashSet は、セット内の要素を一意に保つ必要があるが、順序どおりに配置する必要はない場合に非常に適しています。

HashSet は添え字アクセスをサポートしていません。

ソートセット8742468051c85b06f0a0af9e3e506b5c

SortedSet と HashSet は、SortedDictionary と Dictionary に似ています。この 2 つの違いをまだ覚えていますか? SortedSet は内部的にはバイナリ ツリーでもあり、要素を順番に配置することをサポートするために使用されます。

スタック8742468051c85b06f0a0af9e3e506b5c

後入れ先出しキュー

下付き文字を押してのアクセスはサポートされていません

キュー8742468051c85b06f0a0af9e3e506b5c

先入れ先出しキュー
下付き文字をクリックしてのアクセスはサポートされていません

推奨される使用シナリオ

コレクション

順番に

連順倉庫

直接アクセス方法

訪問時間

稼働時間

備考

辞書

はい

キー:

お(1)

お(1)

アクセスパフォーマンスは最速ですが、ソートはサポートしていません

ソート辞書

順番に並べます

いいえ

キー:
O(ログn)

O(ログn)

高速アクセスと並べ替えのサポートとのトレードオフ

ソートリスト

順番に並べます

はい

キー:

O(ログn)

お(ん)

SortedDictionary と似ていますが、ストレージ構造としてツリーではなくデータが内部的に使用される点が異なります。

リスト

ユーザーは要素の位置を正確に制御できます

はい

インデックス

インデックス: O(1)

値: O(n)

お(ん)

各要素に直接アクセスする必要がある小規模なコレクションに最適です。

リンクリスト

ユーザーは要素の位置を正確に制御できます

いいえ

サポートされていません

値:

お(ん)

お(1)

個々の要素に直接アクセスする必要はないが、コレクションへの非常に頻繁な追加/削除が必要なシナリオに最適です。

ハッシュセット

サポートされていません

はい

キー:

お(1)

お(1)

要素のユニークさを維持したコレクション。並べ替えはサポートされていません

ソートセット

順番に並べます

いいえ

キー:

O(ログn)

O(ログn)

要素の一意性を維持し、並べ替えをサポートできます。

スタック

リフォ

はい

最上位の要素のみを取得できます

トップ: O(1)

お(1)

キュー

先入れ先出し

はい

最下部の要素のみを取得できます

フロント: O(1)

お(1)

非ジェネリッククラスコレクション

ジェネリック コレクション クラスは .NET 2.0 で登場しました。つまり、.NET 1.0 にはそのような便利なものはありませんでした。現在では、古いコードとの互換性を維持するための作業を行う場合を除いて、基本的にこれらのコレクション クラスは使用しません。 1.0 時代に .NET プログラマが使用できるコレクション クラスを見てみましょう。

  1. 配列リスト

後に List8742468051c85b06f0a0af9e3e506b5c に置き換えられました。

  1. HashTable は後に Dictionary に置き換えられました。


  2. Queue は後に Queue8742468051c85b06f0a0af9e3e506b5c に置き換えられました。


  3. SortedList は後に SortedList8742468051c85b06f0a0af9e3e506b5c に置き換えられました。


  4. Stack は後に Stack に置き換えられました。

スレッドセーフなコレクション クラス

  1. ConcurrentQueue Queue のスレッドセーフ バージョン


  2. ConcurrentStack Stack のスレッドセーフ バージョン


  3. ConcurrentBag のスレッドセーフなオブジェクト コレクション


  4. ConcurrentDictionary スレッドセーフな辞書


  5. ブロックコレクション

.NET によって提供されるコレクション クラスは、最も一般的に使用されるツール クラスの 1 つです。この記事が、これらのコレクション クラスについての理解を深めるのに役立つことを願っています。もちろん、個人的にはまだ不完全な点があると感じています。たとえば、HashTable と Binary Search Tree は詳細に研究されていませんし、一方向リンク リストと二重リンク リストの比較についてはこの記事では言及されていません。興味のある友達は、さらに詳しく知ることができます。

以上がC# コレクション型のグラフィック コードの詳細な説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。