212

私はこのようなクラスを書くことに慣れています:

public class foo {
  private string mBar = "bar";
  public string Bar {
    get { return mBar; }
    set { mBar = value; }
  }
  //... other methods, no constructor ...
}

Bar を自動プロパティに変換するのは便利で簡潔に思えますが、コンストラクターを追加してそこに初期化を入れずに初期化を保持するにはどうすればよいでしょうか?

public class foo2theRevengeOfFoo {
  //private string mBar = "bar";
  public string Bar { get; set; }
  //... other methods, no constructor ...
  //behavior has changed.
}

コンストラクターの追加は、自動プロパティから得られるはずの労力の節約と一致していないことがわかります。

このようなものは私にとってより理にかなっています:

public string Bar { get; set; } = "bar";
4

4 に答える 4

249

更新 - 以下の回答は、C# 6 が登場する前に書かれたものです。C# 6 では、次のように記述できます。

public class Foo
{
    public string Bar { get; set; } = "bar";
}

コンストラクターでのみ書き込み可能な読み取り専用の自動実装プロパティを書き込むこともできます (ただし、デフォルトの初期値を指定することもできます)。

public class Foo
{
    public string Bar { get; }

    public Foo(string bar)
    {
        Bar = bar;
    }
}

残念ながら、現在これを行う方法はありません。コンストラクターで値を設定する必要があります。(コンストラクター チェーンを使用すると、重複を避けることができます。)

自動的に実装されたプロパティは今のところ便利ですが、確かにより良いものになる可能性があります。コンストラクターでのみ設定でき、読み取り専用フィールドによってサポートされる読み取り専用の自動的に実装されたプロパティと同じくらい頻繁に、この種の初期化を望んでいるとは思いません。

これは C# 5 までは発生していませんでしたが、C# 6 で計画されています。これは、宣言の時点で初期化を許可することと、読み取り専用で自動的に実装されたプロパティをコンストラクター本体で初期化できるようにすることの両方の観点からです

于 2008-10-04T06:38:02.283 に答える
36

クラスのコンストラクターを介して実行できます。

public class foo {
  public foo(){
    Bar = "bar";
  }
  public string Bar {get;set;}
}

別のコンストラクター (つまり、パラメーターを受け取るコンストラクター) または多数のコンストラクターがある場合は、いつでもこれを使用できます (コンストラクター チェーンと呼ばれます)。

public class foo {
  private foo(){
    Bar = "bar";
    Baz = "baz";
  }
  public foo(int something) : this(){
    //do specialized initialization here
    Baz = string.Format("{0}Baz", something);
  }
  public string Bar {get; set;}
  public string Baz {get; set;}
}

呼び出しを常に既定のコンストラクターにチェーンする場合は、すべての既定のプロパティの初期化をそこに設定できます。チェーンする場合、チェーンされたコンストラクターは呼び出し元のコンストラクターの前に呼び出されるため、より特化したコンストラクターは、必要に応じて異なる既定値を設定できます。

于 2008-10-03T23:06:09.327 に答える
30

これは C# 6.0 で可能になります。

public int Y { get; } = 2;
于 2014-08-29T20:55:32.753 に答える
3

デフォルトのコンストラクター(もちろん、デフォルト以外のコンストラクターもある場合)で:

public foo() {
    Bar = "bar";
}

とにかく舞台裏で起こっているので、これは私が信じている元のコードよりもパフォーマンスが劣っていません。

于 2008-10-03T23:04:44.570 に答える