【C#】コレクションとか配列とか一体何を使ったらいいワケ？

データをグループ化して一つのオブジェクトとして扱う方法、幾つかあるらしい。
それは知っているが、結局ちゃんとわかっていないから適当に配列に突っ込んンで何とかしようとするのもうやめよう。

愚者を救うべく、我々は調査に赴いた。

# 目次
[1. コレクションとは何か？](#1-コレクションとは何か)
　　[1.1 System.Collections.Generic](#1.1-System.Collections.Generic)
　　[1.2 System.Collections.Concurrent](#1.2-System.Collections.Concurrent)
　　[1.3 System.Collection](#1.3-System.Collection)
　　[1.4 System.Linq](#1.4-System.Linq)
　　[1.5 System.Collection.ObjectModel](#1.5-System.Collection.ObjectModel)
　　[1.6 名前空間ではないが、ReactivePropertyのコレクション](#1.6-名前空間ではないが、ReactivePropertyのコレクション)
[2. コレクションの目的](#2-目的)
[3. 何がいいのか？](#3-何がいいのか)
[4. 悪い(気を付ける)ことは？](#4-悪い気を付けることは)
[5. いつ使えば良いのか](#5-いつ使えばいいのか)
[6. まとめ](#6-まとめ)
[7. 参照](#7-参照)

### 1. コレクションとは何か？
+ 以下で示す名前空間(`System.Collection~)。
+ 広義にはコレクション自体はデータをグループ化されたオブジェクトの総称。
+ 狭義にはIEnumerableを継承したクラスのこと。
+ 又、ICollection<T>インターフェイスを継承したクラスやインターフェイスを指す。

冒頭で配列とコレクションは別物かのように書きましたが、配列も`System.Collection.ICollection`の実装です。
又、後述のArrayListやList<T>も配列と呼ぶことがあるようです。
[++C++//未確認飛行c-配列リスト](https://ufcpp.net/study/algorithm/col_array.html)

狭義には[`System.Array`クラス](https://docs.microsoft.com/ja-jp/dotnet/api/system.array?view=net-5.0)のことを指します。

以下に各名前空間を継承したクラス・インターフェイスの一部を記す。

### 1.1[`System.Collections.Generic`](https://docs.microsoft.com/ja-jp/dotnet/api/system.collections.generic?view=net-5.0)
ジェネリックなコレクションを生成できる。つまり要素が一つのデータ型の場合使う。

+ `IEnumerable<T>`
    + `ICollection<T>`
        + `IDictionary<TKey,TValue>` : KeyとValueのコレクション。Keyによるアクセスなので高速。
        + `IList<T>` : Dictionaryと比較し、添字(インデックス)を使った操作が強味。List<T>ではインデックスを利用した検索・並び替え ・操作ができる。
        + `IReadOnlyCollection<T>`：IEnumerable+Countプロパティというコンパクト。別`System.Collections.ObjectModel.ReadOnlyCollection<T>`とは無縁。
        + `ISet<T>`

### 1.2[`System.Collections.Concurrent`](https://docs.microsoft.com/ja-jp/dotnet/csharp/programming-guide/concepts/collections#BKMK_Concurrent)
複数のスレッドからアクセスする場合。効率的なスレッドセーフ操作が可能。
(スレッドセーフとは:「そのコードを複数のスレッドが同時並行的に実行しても問題が発生しないこと」[Wikipedia-スレッドセーフ](https://ja.wikipedia.org/wiki/%E3%82%B9%E3%83%AC%E3%83%83%E3%83%89%E3%82%BB%E3%83%BC%E3%83%95))

### 1.3[`System.Collection`](https://docs.microsoft.com/ja-jp/dotnet/api/system.collections?view=net-5.0)
要素はObject型として保存される。レガシーなので可能な限りCollection.GenericかCollectionConcurrentを使う。

  + `BitArray`クラス：Bool型で数値を管理する。
  + `ArrayList`クラス:サイズ可変のListとして使える。

### 1.4[`System.Collection.ObjectModel`](https://docs.microsoft.com/ja-jp/dotnet/api/system.collections.objectmodel?view=net-5.0)
   + `ObservableCollection<T>`：変更通知イベントを発生させられる。IObservable<T>やIObserver<T>とは関係ない。
   + `ReadOnlyCollection<T>`：紛らわしいが`IReadOnlyList<T>`、`IList<T>`の実装クラス。IList<T>をラッピングして書き換え不可で公開できる。
   + `ReadOnlyDictionary<T>`
   + `ReadOnlyObservable<T>`

### 1.5[`System.Linq`](https://docs.microsoft.com/ja-jp/dotnet/api/system.linq?=net-5.0)
クエリ発行のために用いる。
   + `ILookup` : `Key:Value` = 1:Nとすることができる。Dictionary<>のElementをList<>にするような無様なことをしなくて済む。
   + `IGrouping`
   + `IQuaryable`

  以下のリンクがTips的によくまとめられておりました。勉強になりました。
[意外と知らない！？ C#の便利なコレクション！](https://qiita.com/hiki_neet_p/items/75bf39838ce580cca92d)
[あまり見かけないけど便利な LINQ メソッド を使いこなす！](https://qiita.com/Nossa/items/434ce8471509f0e563e8)

### 1.6名前空間ではないが、ReactivePropertyのコレクションも同様に記す。
+ ReactiveCollectionクラス
+ ReadOnlyReactiveCollectionクラス：ObservableCollection<T>を監視して、元のコレクションを加工する。
+ IFilteredReadOnlyObservableCollectionインターフェイス

[MVVMをリアクティブプログラミングで快適にReactivePropertyオーバービュー](https://blog.okazuki.jp/entry/2015/12/05/221154)
[github-ReactiveProperty](https://github.com/runceel/ReactiveProperty/blob/main/docs/docs/features/Collections.md)


### 2. 目的
+ 関連するオブジェクトをグループにしてまとめる。  


### 3. 何がいいのか？
配列の場合、数が固定されていたり、型を指定したりなど縛りが強い。
コレクションだと配列よりも柔軟に処理ができる。

### 4. 悪い(気を付ける)ことは？
+ コレクション自体を変更できるという性質が、コードを分かりづらくすることがある。

引数をReadOnlyなものにするなど、メソッドシグネチャ(引数と戻り値)だけでメソッドの振る舞いを分かるようにするのがベスト。    

対策として、IListの代わりにIEnumerable型を使うなどがある。
IEnumerable型は繰り返しの為の型なので、Listの用に中身をAddしたりRemoveしたりはされないと推測できる。分かりやすくなる。  
[引数の型を何でも List にしちゃう奴にそろそろ一言いっておくか](https://qiita.com/lobin-z0x50/items/248db6d0629c7abe47dd)

### 5. いつ使えばいいのか？
データをグループ化したい時の考え方

何の為にグループ化するのか。
イテレーション？ => IEnumerable<T>
並び替え？ => List<T>
高速索引？ => Dictionary<TKey,TValue>
重複削除や演算？ => HashSet<T>

[C#(.NET)コレクションの使い分けヒント](https://qiita.com/takutoy/items/cb1e94c36296108e5fd7)
[コレクションとデータ構造体](https://docs.microsoft.com/ja-jp/dotnet/standard/collections/)

### 6. まとめ
#### コレクションのできること
+ 列挙
+ 内容を配列にコピー
+ 要素数・要素の処理
+ 複数スレッドからのアクセス同期

コレクション…というよりIEnumerable<T>を継承したクラス・I/Fは
類似した名称でありながら、名前空間すら違うという紛らわしい世界を形成している。
用途・メンテナンス性を考慮して選ばなければならない。


IEnumerable<T>をLinqで廻した後にToList<T>やToArrayでリストや配列にしているのをよく見るが
その後データを追加・削除するならリスト、しないなら配列に変換する。

端からIReadOnlyListかIReadOnlyCollectionにしてもいい。


======================================================================================================
コレクションという漠然としたテーマで調べたがひとえに説明できないほど風呂敷が広がってしまった。  
調べきれなかったことも多大にあるが今回はこれにとどめておく。

`System.Collections.Concurrent`の辺りは追々追記したい。という気持ちはある。気持ちは。

======================================================================================================

### 7. 参照
[コレクション (C#)](https://docs.microsoft.com/ja-jp/dotnet/csharp/programming-guide/concepts/collections#BKMK_KindsOfCollections)
[System.Linq](https://docs.microsoft.com/ja-jp/dotnet/api/system.linq?=net-5.0)
[System.Collection.ObjectModel](https://docs.microsoft.com/ja-jp/dotnet/api/system.collections.objectmodel?view=net-5.0)
[System.Collection](https://docs.microsoft.com/ja-jp/dotnet/api/system.collections?view=net-5.0)
[System.Collections.Concurrent](https://docs.microsoft.com/ja-jp/dotnet/csharp/programming-guide/concepts/collections#BKMK_Concurrent)
[System.Collections.Generic](https://docs.microsoft.com/ja-jp/dotnet/api/system.collections.generic?view=net-5.0)
[System.Collections.Generic](https://docs.microsoft.com/ja-jp/dotnet/api/system.collections.generic?view=net-5.0)
[引数の型を何でも List にしちゃう奴にそろそろ一言いっておくか](https://qiita.com/lobin-z0x50/items/248db6d0629c7abe47dd)
[MVVMをリアクティブプログラミングで快適にReactivePropertyオーバービュー](https://blog.okazuki.jp/entry/2015/12/05/221154)
[github-ReactiveProperty](https://github.com/runceel/ReactiveProperty/blob/main/docs/docs/features/Collections.md)
[意外と知らない！？ C#の便利なコレクション！](https://qiita.com/hiki_neet_p/items/75bf39838ce580cca92d)
[あまり見かけないけど便利な LINQ メソッド を使いこなす！](https://qiita.com/Nossa/items/434ce8471509f0e563e8)
[コレクションとデータ構造体](https://docs.microsoft.com/ja-jp/dotnet/standard/collections/)