1. ホーム
  2. c#

[解決済み] C#のメンバ変数の初期化、ベストプラクティス?

2023-02-02 05:19:05

質問

宣言時にクラスのメンバ変数を初期化した方が良いのでしょうか?

private List<Thing> _things = new List<Thing>();
private int _arb = 99;

それともデフォルトのコンストラクタで?

private List<Thing> _things;
private int _arb;

public TheClass()
{
  _things = new List<Thing>();
  _arb = 99;
}

それは単にスタイルの問題なのでしょうか、それとも一方にパフォーマンスのトレードオフがあるのでしょうか?

どのように解決するのですか?

フィールドの初期化はコンストラクタのロジックとして実装されます。唯一の違いは、フィールド初期化子はどの "base"/"this" コンストラクタの前でも起こるということです。

コンストラクタのアプローチは、自動実装のプロパティで使用することができます (フィールド初期化機能は使用できません)。

[DefaultValue("")]
public string Foo {get;set;}
public Bar() { // ctor
  Foo = "";
}

それ以外の点では、私はフィールド初期化構文を好む傾向があります; その方がローカライズされた状態を保てるからです。

private readonly List<SomeClass> items = new List<SomeClass>();
public List<SomeClass> Items {get {return items;}}

どこに割り当てられているのか、上下に探し回る必要はないのですが...。

明らかな例外は、複雑なロジックを実行したり、コンストラクタのパラメータを処理したりする必要がある場合です。この場合、コンストラクタベースの初期化を行うのが望ましいと言えます。同様に、複数のコンストラクタがある場合、フィールドは常に同じ方法で設定されることが望ましいでしょう。

public Bar() : this("") {}
public Bar(string foo) {Foo = foo;}

edit: 余談ですが、上記の例では、フィールド初期化子を持つ他のフィールド(表示されていません)がある場合、それらは base(...) - すなわち public Bar(string foo) のコンストラクタです。もうひとつのコンストラクタは ではなく によって実行されることを知っているので、フィールド初期化を実行しません。 this(...) ctorによって行われることを知っているからです。