回答:
はい、どちらも読み取り専用ですが、違いがあります。最初のものには、コンストラクターが実行される前に0に初期化されるバッキングフィールドがあります。値はコンストラクターでのみ変更できます通常の読み取り専用フィールドと同様にでます。ゲッター自体はフィールドの値を返すだけです。
2番目の例では、ゲッターは毎回0を返すだけで、フィールドは関係しません。
したがって、自動的に実装されるプロパティまたは式本体のメンバーをまったく使用しないようにするために、次のようにします。
最初のバージョン
private readonly int _number = 0;
public int Number { get { return _number; } }
2番目のバージョン
public int Number { get { return 0; } }
違いの明確な例は次のようになります。
public DateTime CreationTime { get; } = DateTime.UtcNow;
public DateTime CurrentTime => DateTime.UtcNow;
単一のオブジェクトを作成する場合、そのCreationTime
プロパティは常に同じ結果になります。これは、オブジェクトの構築時に初期化される読み取り専用フィールドに格納されるためです。ただし、CurrentTime
プロパティにアクセスするたびDateTime.UtcNow
に評価されるため、結果が異なる可能性があります。
1つの違いは、それ0
が評価されるときです。オブジェクトの作成時またはプロパティが使用されるときです。
これは、DateTimeプロパティを使用するとよくわかります。
class SomeTestClass
{
public DateTime Start { get; } = DateTime.Now;
public DateTime Now => DateTime.Now;
}
Start
プロパティは、一方で、(インスタンスが作成されたときの)同じ時間を返す続けるNow
の変更は、現在の時刻を反映します。
説明:
最初のバージョン(「開始」)は、コンストラクターによって上書きされる可能性さえある初期値を提供します。したがって、これは一度だけ評価されます。
2番目のバージョン( "Now")は、このプロパティの "ゲッター"になる式を提供します。したがって、これはプロパティが読み取られるたびに評価されます。コンストラクターが上書きできるバッキングフィールドもありません。
これらはC#6言語機能です。
最初の例
public int Number { get; } = 0
最初の例は、ゲッターのみの自動プロパティです。ゲッターのみの自動プロパティのバッキングフィールドは、暗黙的に読み取り専用として宣言されます。
2番目の例
public int Number => 0;
2番目の例は、プロパティのような関数メンバーの式本体です。get
キーワードがないことに注意してください。これは、式の本文の構文の使用によって暗示されています。
どちらも読み取り専用です。
random.NextInt()
た場合です。最初のバージョンはそれを一度評価し、常に同じ値を持ちます。2番目は毎回新しい値を返します。