プロパティを決定論的としてマークする方法はC#にありますか?
私が尋ねる理由は、プロパティに何度もアクセスするのではなく、ローカル変数を宣言してプロパティを読み込むことがよくあるからです。
コンパイラがそのプロパティへの複数のアクセスを最適化できるように、プロパティを決定論的として装飾する方法はありますか?そのようなシナリオでは、クラスは不変であり、そのように装飾されている必要があると推測しています。
これは存在するものですか、それとも私はストローをつかんでいますか?
プロパティを決定論的としてマークする方法はC#にありますか?
私が尋ねる理由は、プロパティに何度もアクセスするのではなく、ローカル変数を宣言してプロパティを読み込むことがよくあるからです。
コンパイラがそのプロパティへの複数のアクセスを最適化できるように、プロパティを決定論的として装飾する方法はありますか?そのようなシナリオでは、クラスは不変であり、そのように装飾されている必要があると推測しています。
これは存在するものですか、それとも私はストローをつかんでいますか?
プロパティが暗黙的なプロパティのように単純な場合:
public int X { get; set; }
またはローカル変数から読み取る:
public int X { get { return _x; } }
次に、コンパイラはコードを最適化して、プロパティに複数回アクセスすることと、プロパティを変数に入れてアクセスすることに違いがないようにします。
プロパティに 10 回アクセスし、プロパティを変数にコピーして 10 回アクセスするという 1 億回の反復を比較することでこれを検証しましたが、測定可能な違いはまったくありません。
一般に、プロパティは軽量である必要があるため、アクセスするたびに重い処理を行う必要はありません。プロパティの値を取得するのにコストがかかる場合、クラスは値を内部的にキャッシュして、プロパティの読み取りがコストのかかる操作を最初の 1 回だけにするようにする必要があります (遅延読み込みパターン)。
プロパティを毎回取得するのにコストがかかる場合は、プロパティではなく、getter メソッドにする必要があります。
C#には、constプロパティゲッター、つまりオブジェクトの状態を変更しないゲッターを導入できるメカニズムはありません。
Microsoftのドキュメントでは、ゲッターに副作用を導入しないことを推奨しています。
getアクセサーを使用してオブジェクトの状態を変更するのは悪いプログラミングスタイルです。たとえば、次のアクセサは、数値フィールドにアクセスするたびにオブジェクトの状態を変更するという副作用を引き起こします。
private int number; public int Number { get { return number++; // Don't do this } }
Darenが述べたように、考慮すべきもう1つの側面は、マルチスレッドです(オブジェクトが本当に不変でない限り)。別のスレッドがオブジェクトの状態を変更して、ゲッターが2回目の呼び出しで異なる値を返すようにした場合はどうなりますか?以下のシナリオのように、コンパイラが保証を行う簡単な方法はありません。
class List
{
IList data;
// called several times on thread A
// property has no side-effects
public int Count { get data.Length; }
// called several times on thread B
public void Add(object o)
{
data.Add(o);
}
}
を探していると思いますがreadonly
、パフォーマンスがローカル変数とどのように比較されるかはわかりません。また、プロパティではなく、フィールドにのみ適用されます。
またreadonly
、決定論を意味するものではありません。
private readonly List<string> fixedList = new List<string>();
ただ、fixedList オブジェクトを置き換えることはできませんが、コンテンツは変更できることを意味します。
プロパティのバッキングフィールドがでreadonly
ある場合を除き、スレッドの問題をどのように説明しますか?