2009-07-08 18 views
5

コンストラクタの外側でオブジェクトを初期化してカプセル化を解除しないでください。考えるC#オブジェクトの初期化オプション

:代わりに、オブジェクトの初期化の代替方法の

MyClass test = new MyClass("test"); 

class MyClass 
{ 
    public string _aString; 
} 

は_aStringメンバーは、コンストラクタ(コンストラクタがここでは省略)への呼び出しを経由してプライベートおよびインスタンス化しないでください:

MyClass test = new MyClass { _aString = "Test" }; 
+0

うわー!すぐに5つの答え!みんな、ありがとう。 このコードはC#の本にあります。私はそれがベストプラクティスかどうかについて興味があった。 –

答えて

6

"コンストラクタの外側でオブジェクトを初期化せずにカプセル化を解除しますか?"

あなたが正しく指摘したように、現在のスコープですでにアクセス可能なプロパティのみを初期化することができます。

この種の初期化は、実際にはクラスの構築や構文の代入に値を割り当てます。匿名クラスとLinqの選択句には非常に便利です。

5

一般に公開されているfiフィールドがreadonlyとマークされている場合(コンストラクタで設定する必要があることなど)、場合によっては許容される場合があります。代わりに、このフィールドはプライベートにし、またはその目的に応じて、読み取り専用であってもなくてもよいプロパティを通してそれを公開する必要があります:それは、変数の目的に依存

class MyClass 
{ 
    private string _aString; 
    public string AString 
    { 
     get { return _aString; } 
     // uncomment to make the property writable 
     //set { _aString = value; } 
    } 
} 
0

。プログラマが初期化時に変数を設定できるだけで、その後はその変数にアクセスできない場合は、private変数を使用します。クラスのユーザがいつでも変数を設定/読み込めるようにするには、その変数を公開します。

0

あなたは
public string _aString;
を持っている場合、これはすでに公開されているので、あなたがこの値を初期化するとき、それは本当に問題ではありません。ですから、初期化について話したいときは、この文字列をプロパティに移動する必要があります。カプセル化についての話は理にかなっています。
文字列があるとします。初期化には2つのアプローチがあります。 1つはコンストラクタ内で行い、2つ目は遅延初期化です(このデータを要求するときに初期化します)。

0

はい、コンストラクタを使用して初期化し、データにアクセスできるようにする(またはしない)プロパティを追加します。

class MyClass { 
private string _aString; 
string MyProperty { 
        get { return this._aString; } 
        // you can make this private or protected 
        set { this._aString = value; } 

        } 
} 
1

ゲッターとセッターとしてプロパティを考えると、私はカプセル化を破るとは思わない。しかし、あなたはPropertyを使用していないことに気付かなければなりません。インスタンス変数を使用しました。実際、私はあなたの例のように動作するとは思わない。これをチェックしてください:

class MyClass { 
    private string aString; 

    public string AString { 
     get { return aString; } 
     set {aString = value; } 
    } 
} 
MyClass test = new MyClass { 
    AString = "test" 
}; 

この場合、あなたはそのフィールドのアクセサーを介してプライベートフィールドにアクセスしています。これは、パラメータのないコンストラクタを使用し、後で値を設定するのと同じです。

+1

パブリックフィールドを直接設定するのは、オブジェクトのイニシャライザでは(言語セマンティクスの観点からは適切な設計ではない)、a-okです。 –

+0

私は知りませんでした!ありがとう! = D – Fernando

0

新しいオブジェクト初期化の短縮形がカプセル化を解除するかどうかを確認する場合、答えは「いいえ」です。新しい方法で公開されたスコープメンバーのみを設定できます。

MyClass test = new MyClass { _aString = "Test" }; 

は、C#クラスのオブジェクト国民は「オブジェクト指向プログラミング」の観点から「カプセル化」を破壊しないショーに

MyClass test = new MyClass(); 
test._aString = "Test"; 
0

と同じです。

「良い習慣」の観点からは、この値を更新する動作(チェックなど)を変更すると、外部コードがこのクラスを使用できるため、プロパティを使用するのは良いことではありません。