2016-11-18 16 views
1

クラスでは、クラスメンバーをプライベートとして宣言しますが、プロパティをpublicとして定義します。例えばクラスメンバーはプライベートでプロパティは公開されているのはなぜですか?

public class student 
{ 
    private int StudentId; 
    private string StudentName; 
    private string Address; 
} 

と、この後、我々はメソッドを使用して割り当てます。

しかし、get setのプロパティを使用すると、public likeのようになります。

public class student 
{ 
    public int StudentId {get;set;}; 
    public string StudentName{get;set;}; 
    public string Address{get;set;}; 
} 

この背景には何がありますか?

+2

からmockableとテスト可能な方法でそれを書くためだけの習慣であります"クラスメンバ"または "プロパティ"(ただし、プロパティもメンバです)、それらを静的メンバおよびインスタンスメンバにグループ化するのがより一般的です。通常は実際の実装をカプセル化したいので、アクセス時に発生するバウンドロジックを持たないフィールドは通常プライベートですが、書き込みアクセス権(書き込み対象者)とバウンドロジック(書き込み)はより一般的に公開されています。型の公開面を制御し、実際の実装を非表示にしたいとします。 –

+0

フィールドをプライベートまたはプロパティとしてパブリックとして使用するように強制するものはありませんが、通常、クラスの内部使用のための変数はプライベートであり、取得/設定時にコードを実行できるようにプロパティは外部使用に使用されます。 – Gusman

+2

このソリューションは、あなたの状況をクリアすることがあります:http://stackoverflow.com/questions/295104/what-is-the-difference-between-a-field-and-property-in-c http://softwareengineering.stackexchange .com/questions/133015/private-variable-vs-property –

答えて

1

クラスは、パブリックメンバーの動作を制御する必要があります。すなわちprivate string StudentName;public作られ、その外部コード(外クラスstudent)で使用された場合、彼らは

は、例えば想像しないかを制御します。次に、長さを制限する検証を追加すると決めましたStudentName - どうすればいいですか? StudentNameの値を設定し、そこに検証を追加するコード内のすべてのインスタンス(そしておそらくこのクラスを使用する他の人のコード)を見つける必要があります。

ないあなたがpublic string Student {get; set;}を使用していた場合 - あなたは簡単に検証して明示的な財産であることを、それを変更することができます。

private string _student; 
public string Student 
{ 
    get { return _student; } 
    set { if(value.Length <= 20) _student = value; 
} 

プロパティを使用して、すなわち、それが簡単にクラス内からクラスのメンバーの動作を制御することができますカプセル化と抽象化の維持

0

あなたは権利があります - 通常、プロパティは公開されたものとして使用されます。 けれども:あなたはこのaswellのようにプロパティを定義することができます。

public int StudentId {get; private set;} 

これは、他のクラスは、あなたのプロパティの値を取得するようになりますが、彼らはそれを変更することはできません。

多くの複雑なコントロールを含むアセンブリのようなプロジェクトを開発するとします。あなたが誰かが内部で起こっていることを誰かが操作することを望まないので、あなたが読めるようにするには、コントロールの値は計算されているので、パブリックゲッターではなくプライベートセッターを与えます。

1

これはそれほど問題ではありません。実際のルールは次のとおりです。

すべてのメンバーをできる限り制限的に定義します。

したがって、privateの場合はprivateとなります。それ以外の場合はinternalまたはprotectedにする必要がある場合は、それぞれinternalまたはprotectedです。それ以外の場合は、protected internalでなければなりません。protected internalです。それ以外の場合はpublicであるため、publicを使用する必要があります(継承していないアセンブリの外側にあるものにアクセスする必要があります)。

今、すべてのことは、大部分はprivateフィールド、ほとんどがpublicのプロパティです。

publicフィールドがあるかどうかを考えてみましょう。それは有効であり、うまく動作し、非常に限定されたケースでも役に立ちます。しかし、それはまた、より脆い。 publicを持つことで、他のコードでどんな値に設定することもできます。それは大丈夫です。public私たちは「愚かな値はありません」と言っているからです。*

しかし、突然愚かな値があるとわかったら、フィールドが変更されるたびに何かする必要があります、またはプロパティのみのデータバインディングで作業する必要があります。ここでは、フィールドをプロパティに変えなければならないでしょう。それは大きな変化です。このクラスを使用しているコードは再コンパイルする必要があります。クラスを使用している唯一の人であれば大きな問題ではありませんが、他の人が使用しているライブラリにある場合です。

しかし、プロパティの場合は、自動実装{ get; set; }をカスタム実装{ get { /* do stuff and return value */ } set { /* do stuff */ } }のプロパティに変更するだけでした。クラスの外からは何も変わっていないように見え、何も壊さなかった。

したがって、あなたがフィールドを作成しようとしている場合、99.99%の時間publicあなたはそのためにプロパティを使用する方が良いでしょう。

一方、論理がないprivateプロパティがある場合、getterメソッドとsetterメソッドは私たちに利益をもたらしません。コストはかかりませんが、無意味です。だから代わりにフィールドを使うだけです。私たちが将来私有財産を使う必要がなくなり、再コンパイルしなければならない唯一のコードが問題のクラスだけであり、それをどうにか再コンパイルしていたからです。

ほとんどすべてのフィールドがprivateで、カスタムロジックを持たないほとんどすべてのプロパティがprotectedまたはpublicの場合があります。

*それともprivateまたはinternalクラスだと私たちは愚かな何かにそれを設定していない外部から約束するが、それはあなたができる場合は、それらを作るよりも、約束を強制する方が良いでしょう。

0

フィールドを直接設定するのではなく、プロパティを使用してカプセル化というオブジェクト指向の原則に従います。これには、クラスがそのオブジェクトに含まれるデータのボスであることも含まれます。クラスは、常にデータへのアクセスを制御しておく必要があります(読み書きする場合)。場合によっては、データの一貫性を確保するために追加の手順を実行する必要があることもあります。しかし、彼らがしていない場合でも、彼らのビジネスの誰もないので、発信者に隠されていないという事実(分離の問題)。したがって、単純なルール:オブジェクトデータへのショートカットはありません。もしあなたがそれを手に入れたいのであれば、クラスにあなたにそれを伝えてもらう必要があります。 C#では、これがプロパティの目的です。あなたは &が返さ割り当てられますどのようなコントロールを持っていないので、

0

公共&をさらすクラスのフィールドをマークプロパティを使用して、それらに公共

  1. を作るの背後にある複数の理由がありますが、危険です。

  2. 値が変わるたびにデバッガに侵入したいですか?セッターにブレークポイントを追加するだけです。

  3. すべてのアクセスをログに記録しますか?ゲッターにロギングを追加するだけです。 プロパティはデータバインディングに使用されます。フィールドはそうではありません。

  4. プライベートメンバーにバリデーションを追加します(値をマイナスに設定することはできません)。

  5. null、空またはゼロの場合のデフォルト値を返します。

  6. プロパティは、読み取り/書き込み、読み取り専用、または書き込み専用として宣言できます。

  7. その他の利点、ReflectionおよびDataBinding。

0

この最も簡単なケースでは特別な理由はありません。しかし、開発をさらに進めれば、それは絶対的に明白になるでしょう。実装から抽象化し、インタフェースを分離する必要があります。ユニットテストで学生を模擬するだけです。 *彼らはだからだから、長期的に*あなたはかなりのインターフェイスとプロパティをする必要があります、それはあなたがこれをしない非常に始まる

public interface IStudent 
{ 
    int StudentId { get; set; } 
    string StudentName { get; set; } 
    string Address { get; set; } 
} 

public class Student : IStudent 
{ 
    public int StudentId { get; set; } 
    public string StudentName { get; set; } 
    public string Address { get; set; } 
} 
関連する問題