ジェネリッククラスは多くの目的で非常にうまく機能しますが、参照によって構造体にアクセスするための合理的な方法を提供していません。多くの場合、構造体のコレクションは、クラスオブジェクトのコレクションよりも優れたパフォーマンス(メモリフットプリントの削減とキャッシュの局所性の向上の両方)と明確なセマンティクスを提供するため、これは残念なことです。構造体の配列を使用する場合、非常に明確な効果を持つようなステートメントを使用できます。のフィールドはArrayOfRectangle[5].Width += 3;
更新されますが、タイプの他の格納場所のフィールドには影響しません。それを確実にするために知っておく必要があるのは、それがであり、パブリックフィールドを持つ構造体であるということだけです。クラスであり、インスタンスが保持されている場合X
ArrayOfRectangle[5]
X
Rectangle
ArrayOfRectangle
Rectangle[]
Rectangle
int
X
Rectangle
ArrayOfRectangle[5]
これまで外界にさらされたことがある場合、によって参照されるインスタンスが、そのインスタンスのArrayOfRectangle[5]
フィールドが変更されないことを期待していた他のコードによっても保持されているかどうかを判断するのは困難または不可能である可能性がX
あります。構造を使用すると、このような問題は回避されます。
.netのコレクションの実装方法を考えると、通常、構造体のコピーを作成して変更し、保存するのが最善の方法です。これを行うのはやや厄介ですが、それほど大きくない構造体の場合、値型を使用することで達成されるメモリフットプリントとキャッシュの局所性の向上は、データ構造との間でオブジェクトを明示的にコピーするための余分なコードを上回る可能性があります。不変のクラス型を使用する場合と比較して、ほぼ確実に大きな勝利になります。
ちなみに、私が見たいのは、コレクションが次のようなメソッドを公開することです。
これは、渡されたパラメーターとともにコレクションの適切な要素をOperateOnElement<paramType>(int index, ref T element, ref paramType param, ActionByRef<T,paramType> proc)
呼び出します。proc
このようなルーチンは、多くの場合、クロージャを作成せずに呼び出すことができます。このようなパターンが標準化されていれば、コンパイラーはそれを使用してフィールド更新コードを適切に自動生成することもできます。