2012-05-13 15 views

答えて

4

私にとって、コンストラクタ(デフォルト以外のコンストラクタ)に引数を付けると、より良いテストが可能になります。特定のデータをメンバフィールドに「注入」することは、そのメンバをパブリック(または少なくとも内部)にしたり、「セッタ」プロパティを使用して2番目の呼び出しを行うことなく、必ず実行することはできません。

複数のコンストラクタを持つことができるので、本当に必要な場合は、デフォルトのコンストラクタと組み合わせてテスト用の2番目のコンストラクタを持つことができます。

データをポピュレートするために別の呼び出しを行う必要がないか、クラスへの複数の呼び出しでメンテナンスの難しいコードを持つ必要があります(1つはオブジェクトの作成、 )。

EDIT:私は間違った質問に答えました。私は彼がデフォルトと非デフォルトのコンストラクタの違いについて質問していると思った。今は、コンストラクタ内のメンバーをメンバー宣言で初期化するデフォルトのコンストラクタに関するものです。

+0

ok、パフォーマンスとメモリ割り当てはどうですか? – retide

+1

これは本当に意味をなさない。あなたがコンストラクタとしてそれを提供していない場合、何かを注入することはできませんし、テストのための特定のコンストラクタはcode smellです(それはあまり直接の依存関係を持つクラスを指します)。本当にクラスを分離したい場合は、変更が必要な可能性のあるすべてのパラメータをインタフェースとして使用します。 – Femaref

+0

おそらく、このメンバ変数を使った彼の質問の文脈では、確かにオプションです。私はあなたが多くのプロパティを持っているかもしれない場合、インターフェイスを作成し、それを渡すことに同意します。 – Killnine

1

2つは同等です。コンパイラは、そのようなメンバの初期化をコンストラクタに移します(メンバが静的であれば静的コンストラクタ)。私はそれを行う一般的な最善の方法があるとは言いません - 可能な限り一貫していて、状況に合っていればそれを使用してください。

1

コンストラクタでインスタンスメンバーを初期化し、宣言でクラスメンバーを初期化します。 AFAIKこれは(唯一の)大会であり、パフォーマンスのペナルティはありません。 IMHOこれは言語規則(構文/意味)に強制されるべきです。

10

これらはほぼ同等です(パフォーマンスとメモリ使用量の違いはごくわずかです)。実際の違いは、次のような場合です。

private List<string>name = new List<string>(); 

...割り当ては、オブジェクトのインスタンスを作成するために使用されるコンストラクタに関係なく常に発生します。コンストラクタ内で代入を行うと、そのコンストラクタが使用されたときにのみ代入が行われます。

コンストラクタが複数ある場合でも、常に同じ方法でnameを初期化する必要がある場合は、最初のフォームを使用して各コンストラクタで明示的に初期化するよりも少し短くなります。

しかし、原則として、コードをより冗長にする場合でも、コンストラクタ実装のフィールドを初期化することをお勧めします。 2番目のコンストラクタを呼び出す場合は、不ほとんどすぐに捨てられたとの対象と作られてリストを作成し、このコードで

class MyClass 
{ 
    private List<string> _list = new List<string>(); 
    public MyClass() 
    { 
     //some logic here 
    } 
    public MyClass(List<string> initialList) : this() 
    { 
     _list = initialList; 
    } 
} 

:コンストラクタで

+0

コンパイラは、実際にはどのメンバー初期化コードもすべてのコンストラクタに移動します。これは、使用中の各コンストラクタに対して指示が繰り返される点を除いて、コンストラクタにそれを置くこととはパフォーマンス/メモリ使用の要件の違いが全くないことを意味します(これはインスタンスメンバーのメガバイト分の初期化命令があればこのように宣言され、複数のコンストラクタ)。 –

+0

これは非常に良い説明であり、実際に質問に答えます;)+1 – Killnine

+0

@TimS。フィールドの初期化子をコンストラクタに移動するという主張をバックアップする証拠はありますか? [フィールド初期化子と基本クラスのコンストラクタが同じ順序で呼び出されていないため]、私にとってはそう思わないでしょう(http://blogs.msdn.com/b/ericlippert/archive/2008/02/15/why-do初期化子 - 逆順 - コンストラクター - パート - ワン。aspx)で実行します。フィールド初期化子は、基本クラスのフィールド初期化子の前、およびそのコンストラクタの前で実行されます。コンストラクタは基本クラスのコンストラクタの後に*を実行します。 – phoog

1

初期フィールドはまた、あなたがこの問題を回避することができますガベージコレクション。

関連する問題