7

プロパティを決定論的としてマークする方法はC#にありますか?

私が尋ねる理由は、プロパティに何度もアクセスするのではなく、ローカル変数を宣言してプロパティを読み込むことがよくあるからです。

コンパイラがそのプロパティへの複数のアクセスを最適化できるように、プロパティを決定論的として装飾する方法はありますか?そのようなシナリオでは、クラスは不変であり、そのように装飾されている必要があると推測しています。

これは存在するものですか、それとも私はストローをつかんでいますか?

4

4 に答える 4

8

プロパティが暗黙的なプロパティのように単純な場合:

public int X { get; set; }

またはローカル変数から読み取る:

public int X { get { return _x; } }

次に、コンパイラはコードを最適化して、プロパティに複数回アクセスすることと、プロパティを変数に入れてアクセスすることに違いがないようにします。

プロパティに 10 回アクセスし、プロパティを変数にコピーして 10 回アクセスするという 1 億回の反復を比較することでこれを検証しましたが、測定可能な違いはまったくありません。

一般に、プロパティは軽量である必要があるため、アクセスするたびに重い処理を行う必要はありません。プロパティの値を取得するのにコストがかかる場合、クラスは値を内部的にキャッシュして、プロパティの読み取りがコストのかかる操作を最初の 1 回だけにするようにする必要があります (遅延読み込みパターン)。

プロパティを毎回取得するのにコストがかかる場合は、プロパティではなく、getter メソッドにする必要があります。

于 2010-09-15T09:07:21.783 に答える
5

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);
    }
}
于 2010-09-15T08:55:18.347 に答える
2

を探していると思いますがreadonly、パフォーマンスがローカル変数とどのように比較されるかはわかりません。また、プロパティではなく、フィールドにのみ適用されます。

またreadonly、決定論を意味するものではありません。

private readonly List<string> fixedList = new List<string>();

ただ、fixedList オブジェクトを置き換えることはできませんが、コンテンツは変更できることを意味します。

于 2010-09-15T08:59:48.053 に答える
0

プロパティのバッキングフィールドがでreadonlyある場合を除き、スレッドの問題をどのように説明しますか?

于 2010-09-15T08:52:52.287 に答える