Listでは、あらかじめListの内部に大きめの配列を用意しておき、そこに要素を格納していくことで可変長配列の機能を実現しています。 そのためListでは、実際にListに格納されている要素数よりも大きい配列が自動的に確保されます。 CountプロパティでList内に含まれる要素数を取得することができるのに対し、Capacityプロパティを参照することでList内で確保されている配列の容量を知ることができます。

以下のコードを使って、空のListに1つずつ要素を追加していったときのListの容量の変化を見てみます。

Listの要素数Countと容量Capacityの変化
using System;
using System.Collections.Generic;

class Sample {
  static void Main()
  {
    // 空のListを作成
    var list = new List<int>();

    // 現在の要素数とListの容量を表示
    Console.WriteLine("Count={0} Capacity={1}", list.Count, list.Capacity);

    // 要素を20個追加する
    for (var i = 0; i < 20; i++) {
      list.Add(i);

      // 現在の要素数とListの容量を表示
      Console.WriteLine("Count={0} Capacity={1}", list.Count, list.Capacity);
    }

    Console.WriteLine();

    // Listを空にする
    list.Clear();

    // 現在の要素数とListの容量を表示
    Console.WriteLine("Count={0} Capacity={1}", list.Count, list.Capacity);
  }
}
実行結果
Count=0 Capacity=0
Count=1 Capacity=4
Count=2 Capacity=4
Count=3 Capacity=4
Count=4 Capacity=4
Count=5 Capacity=8
Count=6 Capacity=8
Count=7 Capacity=8
Count=8 Capacity=8
Count=9 Capacity=16
Count=10 Capacity=16
Count=11 Capacity=16
Count=12 Capacity=16
Count=13 Capacity=16
Count=14 Capacity=16
Count=15 Capacity=16
Count=16 Capacity=16
Count=17 Capacity=32
Count=18 Capacity=32
Count=19 Capacity=32
Count=20 Capacity=32

Count=0 Capacity=32

この結果からも、Listでは要素の追加を行う際など必要になった時点で容量を拡張していることがわかります。 また、Clearメソッドを呼び出したあとも容量が変わっていないことがわかります。

このように、Listでは常に格納されている要素数以上の容量を持ちます。 また、Clearメソッドなどによって要素数が減っても一度確保された容量が減ることはありません。 従って、Listに対して多数の要素の追加・削除を行った後には、特に操作を行わないかぎり使われなくなった(必要以上の)領域がそのまま残されることになります。

Listへの要素の追加と、List内部の状態
Listに対する操作 List内部の状態
- 0 1 (空き) (空き)
(操作前の状態)
Count=2
Capacity=4
list.Add(2) 0 1 2 (空き)
(空いている領域があるため、そこに要素が追加される)
Count=3
Capacity=4
list.Add(3) 0 1 2 3
(空いている領域があるため、そこに要素が追加されるが、以降追加するための空き領域がなくなる)
Count=4
Capacity=4
list.Add(4) 0 1 2 3 (空き) (空き) (空き) (空き)
(まずList内で自動的に容量の拡張が行われ、追加するための領域が確保される)
Count=4
Capacity=8
0 1 2 3 4 (空き) (空き) (空き)
(確保された領域に要素が追加される)
Count=5
Capacity=8
ListのクリアとList内部の状態
Listに対する操作 List内部の状態
- 0 1 2 (空き)
(操作前の状態)
Count=3
Capacity=4
list.Clear() (空き) (空き) (空き) (空き)
(すべての要素が削除され、各領域は空き状態になるが、容量自体は削減されない)
Count=0
Capacity=4