ゲッターのプロパティに略語が表示されることがあります。例えば。これら2つのタイプ:
public int Number { get; } = 0
public int Number => 0;
これら2つの間に違いがあるかどうかを教えてください。彼らはどのように振る舞いますか?両方とも読み取り専用ですか?
はい、両方とも読み取り専用ですが、違いがあります。最初のものには、コンストラクターが実行される前に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
は現在の時刻を反映するように変更されます。
説明:
最初のバージョン( "Start")は、コンストラクターによって上書きされる可能性のある初期値を提供します。したがって、これは一度だけ評価されます。
2番目のバージョン( "Now")は、このプロパティの "getter"になる式を提供します。したがって、これはプロパティが読み取られるたびに評価されます。コンストラクターが上書きできるバッキングフィールドさえありません。
これらはC#6言語機能です。
最初の例
public int Number { get; } = 0
最初の例は getter-only auto property です。ゲッター専用自動プロパティのバッキングフィールドは、暗黙的に読み取り専用として宣言されます。
2番目の例
public int Number => 0;
2番目の例は、 プロパティのような関数メンバーの式本体 です。 get
キーワードはないことに注意してください。これは、式本体構文の使用によって暗示されます。
両方とも読み取り専用です。