6

現在、C#でのデータのカプセル化について考えていますが、少し混乱しています。数年前、私がC ++でプログラミングを学び始めたとき、私の教授は私にこう言いました:-「クラスを作成し、それをデータメンバーに隠して、外部から直接操作できないようにする」

例:XMLファイルを解析し、解析されたデータをパーサークラス内のいくつかのデータメンバーに格納します。

さて、C#を見ているとき。そこにプロパティがあります。この機能により、クラスの内部状態/内部データが外部に表示されます。もうカプセル化はありません。右?

private string _mystring;
public string MyString
{
  get {return _mystring;}
  set {_mystring = value;}
}

私の見解では、データメンバーを公開することと、プライベートデータメンバーを通過させるゲッターとセッターを持つパブリックプロパティを持つことの間に違いはありません。

誰かが私にそれを説明してもらえますか?

ありがとう

4

7 に答える 7

16

プライベートデータは、プロパティ自体によってカプセル化されます。データにアクセスする唯一の方法は、プロパティを使用することです。

上記の状況では、プロパティを使用する理由はほとんどありません。ただし、後で検証を追加する必要がある場合は、APIを壊すことなく、次のようにできます。

private string _mystring;
public string MyString
{
  get {return _mystring;}
  set 
  {
      if (IsAcceptableInput(value))
         _mystring = value;
  }
}

.NETのプロパティは、実際には2つのメソッドのよりクリーンな構文であることに注意してください。1つはプロパティgetセクション用、もう1つはプロパティsetセクション用です。これは、C ++のメソッドのペアと同じカプセル化をすべて提供しますが、(おそらく)使用法としてより優れた構文を提供します。

于 2010-09-17T22:04:44.130 に答える
2

そうですね、プロパティは一見しただけの西部開拓時代ではありません。OOPの不幸な真実は、メソッドの多くがゲッターとセッターであり、プロパティはこれを記述しやすくするための単なる方法であるということです。また、誰かができるようにプロパティに何をしたいかを制御します。次のように、プロパティを読み取り可能にすることはできますが、書き込み可能にすることはできません。

private string _mystring;
public string MyString
{
  get {return _mystring;}
}

または、Reedが述べたように、setメソッドに変換または複雑さのチェックを実行させることができます。たとえば、

private long myPrime;
public long Prime {
   get { return myPrime; }
   set { 
     if (prime(value) {
        myPrime = prime;
     }
     else {
        //throw an error or do nothing
     }
   }
}

一般に、カプセル化から得られるすべての価値があり、いくつかの一般的なタスクを簡単にするための構文糖衣が含まれています。プロパティが他の言語で行うのと同じことを行うことができますが、見た目が異なるだけです。

于 2010-09-17T22:09:33.727 に答える
1

プロパティの利点は、後でsetterメソッドに検証などを追加したり、getterメソッドに計算やキャッシュを実行させたりすることができ、プロパティを既に呼び出しているコードを変更する必要がないことです。 'インターフェースは安定したまま

于 2010-09-17T22:04:09.103 に答える
1

必要に応じて、データのカプセル化はまだあります。データのカプセル化とは、データをクラスのクライアントから隠したり、アクセスできなくしたりすることではなく、一貫したインターフェイスと内部オブジェクトの状態を確保することです。

スティックシフトカーを表すオブジェクトと、速度を設定するプロパティがあるとします。あなたはおそらく、速度間隔の間にギアをシフトする必要があることを知っているでしょう、それでカプセル化が入ります。

プロパティを単純に公開して検証なしでパブリックアクセスを許可する代わりに、C#でプロパティゲッターとセッターを使用できます。

class StickShiftCar : Car
{
    public int MilesPerHour
    {
        get {return this._milesPerHour;}

        set 
        {
          if (vaule < 20)
              this._gearPosition = 1;
          else if (value > 30)
              this._gearPosition = 2;
          ...
          ...
          this._milesPerHour = value;
  }
}

この例は必ずしもコンパイル可能ではありませんが、私のドリフトを捕まえると確信しています。

于 2010-09-17T22:08:06.070 に答える
1

すべてのクラス メンバー フィールドに対応するプロパティが必要ないという事実を見落としている可能性があります。クラスに追加するプロパティと、クラス外からアクセスできるかどうかを決定できます。

于 2010-09-17T23:28:00.060 に答える
0

もう少し詳しく見てみると、なぜあなたの教授はあなたにカプセル化するように言ったのですか? それが適切なオブジェクト指向設計だからですか?なぜそれが適切な方法なのですか?プログラミング言語とパラダイムは、プロセッサにコードを理解できる方法で実行させる複雑さに対処する方法にすぎません。コードの読み取りには、機械と人間の 2 人がいます。マシンは、メモリ空間内の任意のアドレスからデータをロードしたり、そこに分岐したりします。一方、私たち人間は「もの」について考えるのが好きです。私たちの脳は、属性を持つものや行動を起こす「もの」を扱います。ライオンはあなたを食べます、槍はあなたを守ることができます、ライオンは毛皮で覆われています、槍はとがっています. ですから、プログラムを「モノ」としてモデル化すれば理解できます。プロパティは、物の属性をモデル化することになっています。メソッドは、物事のアクションをモデル化することになっています。実際には、非常にあいまいになる可能性があり、すべてを現実世界のアクションとしてモデル化することはできません。

于 2010-09-17T23:23:00.617 に答える