1

ILSpyを使用してmscorlibライブラリを逆コンパイルし、List.ClearメソッドがArray.Clear(this._items, 0, this._size)内部で使用していることに気付きました。

// System.Collections.Generic.List<T>
/// <summary>Removes all elements from the <see cref="T:System.Collections.Generic.List`1" />.</summary>
public void Clear()
{
    if (this._size > 0)
    {
        Array.Clear(this._items, 0, this._size);
        this._size = 0;
    }
    this._version++;
}

次に、このArray.Clearメソッドは、すべての配列要素をゼロ、false、またはnullに設定します。また、メソッドList.RemoveRangeを使用しています。Array.Clear

// System.Array
/// <summary>Sets a range of elements in the <see cref="T:System.Array" /> to zero, to false, or to null, depending on the element type.</summary>
/// <param name="array">The <see cref="T:System.Array" /> whose elements need to be cleared.</param>
/// <param name="index">The starting index of the range of elements to clear.</param>
/// <param name="length">The number of elements to clear.</param>
/// <exception cref="T:System.ArgumentNullException">
/// <paramref name="array" /> is null.</exception>
/// <exception cref="T:System.IndexOutOfRangeException">
/// <paramref name="index" /> is less than the lower bound of <paramref name="array" />.-or-<paramref name="length" /> is less than zero.-or-The sum of <paramref name="index" /> and <paramref name="length" /> is greater than the size of the <see cref="T:System.Array" />.</exception>
/// <filterpriority>1</filterpriority>
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success), SecuritySafeCritical]
[MethodImpl(MethodImplOptions.InternalCall)]
public static extern void Clear(Array array, int index, int length);

Array.Clear(this._items, 0, this._size)値型の最初のコードリストで呼び出されるメソッドを無視することは可能ですか?必要ないと思います。私は正しいですか?

この質問は、リストだけでなく、他の一般的なコレクションにも当てはまります。

4

2 に答える 2

3

_sizeガベージコレクターは、それ以降の要素が論理的に到達不能であることを認識していません。表示されるのはオブジェクトへのハンドルでいっぱいの配列だけなので、それらのオブジェクトをすべて存続させる必要があります。このため、実際にすべてのハンドルをに設定するnullことは、ガベージコレクターがリストから削除されたばかりのオブジェクトをクリーンアップできるようにするために、コンテナーをクリアするために必要な部分です(プログラムの他の部分にハンドルがない場合)。

プリミティブ型(List<int>)の場合、これは必要ありませんが、.NETではジェネリック型を特殊化することはできません。値型にはハンドルを含めることができるため、.NETに特殊化されていても、値型を最適化することはできません。

于 2012-09-28T13:28:50.597 に答える
0

アレイの場合 リストについてはできます。

配列はメモリを事前に割り当てるため、これらの要素をデフォルトで何かに設定する必要があることに注意してください(数値の場合は0です)。

ここで、リストの場合、リストの最初の要素へのヘッダーポインターがあり、リストヘッダーをnullにポイントし、必要に応じて長さ変数を0に設定するだけで、次のようになります。すべての要素に触れることなく、リストは空(クリア)になります。現在、これはADTリンクリストにあります。

.NET CLRリストでは、実装によってClear操作がO(N)であり、参照を解放するためにリストをトラバースする必要があることが明確になっていますが、これはなぜですか?Java仕様(これは.NETですが)は、その理由を理解できると思います。

ノード間のすべてのリンクをクリアすることは「不要」ですが、次のようになります。-破棄されたノードが複数の世代に存在する場合に世代GCを支援します-到達可能なイテレータが存在する場合でも、確実にメモリを解放します

于 2012-09-28T13:16:28.797 に答える