2017-09-05 2 views
151

ゲッターのプロパティで略字が表示されることがあります。例えば。異なるゲッタースタイル間のC#の違い

public int Number { get; } = 0 

public int Number => 0; 

これらの2つの違いがあるかどうか教えてもらえますか?彼らはどのように行動するのですか?両方とも読み込み専用ですか?

答えて

262

はい、どちらも読み取り専用ですが、違いがあります。最初のものには、コンストラクタが実行される前にバッキングフィールドが0に初期化されています。通常の読み取り専用フィールドのように、の値をコンストラクタでのみ変更することができます。ゲッター自体はフィールドの値を返します。

ゲッターは、毎回0を返し、フィールドは関与しません。

だから、まったく自動的に実装プロパティまたは式ボディのメンバーの使用を避けるために、我々は持っている:

最初のバージョン

private readonly int _number = 0; 
public int Number { get { return _number; } } 

セカンドバージョン

public int Number { get { return 0; } } 

A違いの明確な例は次のように見えます:

public DateTime CreationTime { get; } = DateTime.UtcNow; 
public DateTime CurrentTime => DateTime.UtcNow; 

あなたは、単一のオブジェクトを作成する場合は、そのCreationTimeプロパティは常に同じ結果が得られます - それは読み取り専用フィールドに格納されているため、オブジェクトの構築に初期化。ただし、CurrentTimeプロパティにアクセスするたびにDateTime.UtcNowが評価されるため、結果が異なる可能性があります。

+22

第2のバージョンが常に同じ値を返すとは限りません。一つの良い例は 'random.NextInt()'を返す場合です。最初のバージョンはそれを一度評価し、常に同じ値を持ちます。 2回目は毎回新しい値を返します。 – Hosch250

20

これらはC#6の言語機能です。

まず例

public int Number { get; } = 0 

最初の例では、getter-only auto propertyあります。ゲッター専用の自動プロパティのバッキングフィールドは、読み取り専用として暗黙のうちに宣言されます。

第二の例

public int Number => 0; 

そして、第二の例はexpression bodies on property-like function membersです。 getキーワードがないことに注意してください。これは、式の本文構文を使用することによって暗示されます。

両方が読み取り専用です。

+4

... Jon Skeetが説明しているように、最初のものが返す値を変更できます。 –

+1

@MartinBonner ...コンストラクタでのみです。 –

+4

またはいつものように、反射(軽微なニックピッキング) –

246

1つの違いは、0が評価されるときです。オブジェクトの作成時またはプロパティの使用時です。

あなたは、日付と時刻のプロパティでこれよりよく見ることができます:

class SomeTestClass 
{ 
    public DateTime Start { get; } = DateTime.Now; 

    public DateTime Now => DateTime.Now; 
} 

StartプロパティはNow変更は、現在の時刻を反映している間、(インスタンスが作成されたときの)同じ時間を返し続けます。

説明

最初のバージョン(「スタート」)もコンストラクタによって上書きすることができる初期値を供給する。これはただ一度評価されます。
2番目のバージョン(「Now」)は、このプロパティの「ゲッター」となる式を提供します。これはプロパティが読み込まれるたびに評価されます。コンストラクタが上書きできるバッキングフィールドもありません。

+24

これは私が考える最も重要な違いです。 – Matthew

+13

受け入れられた答えはサンプルコードの違いを最も正確に定義しますが、これは2つの構造のより有用な違いを説明しています。 –

+2

うわー、あなたは有名なJon Skeet自身よりももっと票を集めました。 –

関連する問題