0

重複の可能性:
ベスト プラクティス: コンストラクターまたは宣言時にクラス フィールドを初期化しますか?

これは、現在のプロジェクトについて話しているときに私と私の友人が提起した、単純で少しばかげた疑いです。

私が知りたいのは、以下の例のように、C# を使用してクラスのコンストラクターの内部と外部で変数を設定するメソッドを呼び出すことの違いです。

ケース 1:

public class Test
{
    string myVar = GetValue();

    public Test()
    {
    }
}

ケース 2:

public class Test
{
    string myVar;

    public Test()
    {
        myVar = GetValue(); 
    }
}

これらのアプローチのいずれかを使用する場合、パフォーマンスの違いや「パターン違反」はありますか? これらのアプローチのどれが優れているか、コンパイラーレベルでそれらを使用すると実際に何が起こるかを誰かが教えてくれれば、本当に感謝しています。

前もって感謝します!

4

4 に答える 4

1

AFAIK の唯一の違いは、フィールドの初期化 (最初の例) が最初にトリガーされることです。基本的にはコンストラクター コードとして扱われます。どちらかを選択してもパフォーマンスが向上するわけではありません。実際には好みの問題です。

クラス階層に基づいて変更される可能性があるため、注意すべきことの 1 つは実行順序です。

于 2013-01-09T12:07:37.640 に答える
1

メソッドGetValueがクラスの静的メソッドである場合は、フィールドの初期化で使用できます。インスタンスメソッドの場合、エラーが発生します。

最初のコードではフィールドの初期化を使用していますが、2 番目のコードではコンストラクターでフィールドを初期化しています。

フィールド C#

フィールドは、オブジェクト インスタンスのコンストラクターが呼び出される直前に初期化されるため、コンストラクターがフィールドの値を割り当てると、フィールド宣言中に指定された値が上書きされます。

どちらが優れているかは、あなたの要件次第だと思います。通常、フィールドに割り当てたいパラメーターをコンストラクターに渡す場合は、コンストラクターでのみ行うことができます。ただし、コンストラクターの実行前にフィールドのデフォルト値が必要な場合は、フィールド初期化子を使用することをお勧めします。

于 2013-01-09T12:11:37.743 に答える
0

あなたが投稿したコードはコンパイルされていないので、いくつかの可能なバリエーションを作成しました。

1.静的フィールドと静的メソッド

public class Test
{
    static string myVar = GetValue();

    public Test()
    {
    }

    static string GetValue()
    {
        return String.Empty;
    }
}

この場合、静的フィールドをどこに設定するかは実際には問題ではありません:静的コンストラクター (コードには表示されません) または静的フィールドの初期化として。CLR は、型が AppDomain に読み込まれるときに両方を初期化します。(CLR が最初に静的コンストラクターを呼び出してからすべての静的フィールドを設定する、またはその逆のようなシーケンスがありますが、このシーケンスは制御できません)。

2. コンストラクターでのプロパティの設定

public class Test1
{
    string MyVar{get;set;}
        
    public Test1()
    {
        MyVar = GetValue();
    }

    string GetValue()
    {
        return String.Empty;
    }
}

種類や用途によって異なります。この特定のケースでは、コンストラクターは軽量であることを意図しているため、おそらくこれを避けるでしょう。重い処理を行う場合は、これInitializeを適切なエラー処理とtry-catchブロックを備えたメソッドに移動することをお勧めします。プロパティを設定するのに手間がかからない場合は、コンストラクターにMyVar = "EMPTY".

3. 別のクラスでプロパティを設定する

public class Test
{
    public string MyVar{get;set;}
        
    public Test(){ }

    public string GetValue()
    {
        return String.Empty;
    }
}

//somewere else 
Test t = new Test();
t.MyVar = t.GetValue();

クラスが状態 (プロパティ) を提供し、現在の状態 (GetValue メソッド) を取得する手段であるため、これは少し奇妙に見えます。この場合の 2 つのメンバー (プロパティとメソッド) は、おそらく単一のgetterにマージされます。

于 2013-01-09T12:26:18.333 に答える
0

フィールドの初期化が実現可能で、可読性が向上する 1 つのケースは、次のケースです。

class Test
{
    string myVar;
    string anotherVar;

    public Test()
    {
        myVar = "one default";
        anotherVar = "another default";
    }
    public Test(string s) //: this()
    {
        myVar = s;
        anotherVar = "another default";
    }
}

場合によっては、いくつかの変数を2回初期化するのが間違っている可能性があるため、デフォルトでコンストラクターを呼び出したくないでしょう(私の場合は間違いなく問題ありません)。したがって、上記の例ではanotherVar、フィールドの初期化に移ります。

注:パフォーマンスについて言えば、私はそのようなナノ最適化レベルではありません-フィールド初期化を使用すると、フィールドは必要に応じて最初の値を受け取ります。コンストラクターから初期化すると、すでにデフォルト値があるため、技術的に言えば、フィールドを2回割り当てます。しかし、このペナルティは非常に小さいため、妥当なシナリオは想像できません。

于 2013-01-09T12:18:34.620 に答える