4

変数、メソッド、およびクラスは、さまざまなセキュリティ レベルを受け取ることができます。私の C# の経験から、次のようなものがあります。

パブリック
内部
保護
保護 内部
プライベート

これで、メソッドとクラスを非公開にする、または内部または保護することの使用法は理解できましたが、変数についてはどうでしょうか? 変数を private にしても、Property を使って別のクラスから呼び出すことができます。

私は常に、プロパティがベストプラクティスであると考えてきました。したがって、それを使用できれば、インスタンスを介して変数を直接呼び出す必要はありません。

変数をプライベートにしない理由はありますか?

編集: プロパティについて、あたかも栄光のパブリック変数に過ぎないかのように話している人がいます。

簡単な注意: public 変数はその値だけを返します。プロパティを使用すると、さらに多くのことができます。例えば:

public int AmountOfBooks{
  get {
    //code to check certain conditions
    //maybe trigger an event while we're at it.
    //and a few conditionals.
    return this.amountOfBooks;
  }

  set {
    //a few conditionals
    //maybe trigger an event
    this.amountOfBooks = value;
    //and I can do even more... I think, never tried this.
  }
}

私のプロフィールを読んだ人は、私が学生であることを知っています。プロパティを「美化されたパブリック変数」として使用することは、多くの仲間の学生が行っていることです。彼らにこれができると言ったときの最も一般的な反応は、「それは許されますか?」です。

4

8 に答える 8

14

確かに、public フィールドを持つことが理にかなっている状況はあります。たとえば、既存のアンマネージ win32 API との相互運用性のみを目的として構造体を作成している場合です。

ただし、通常のマネージド オブジェクト モデルを構築する場合のベスト プラクティスは、オブジェクトのプロパティをプロパティとしてモデル化し、パブリックに公開された機能を非公開で実装するメカニズムとしてフィールドを使用することです。

更新: この機会に、バッキング ストアにアクセスするだけのプロパティを C# 3.0 で非常に簡単に記述できるようにしようとしたことに注意してください。

public int Foo { get; set; }

とまったく同じです

private int _Foo;
public int Foo { get { return _Foo; } set { _Foo = value; } }

しかし、はるかに短く、読みやすくなっています。もちろん、後でバッキング ストアを使用して長い形式に拡張する必要がある場合は、互換性に影響する変更ではありません。

これを行うこともできます:

public int Foo { get; private set; }

クラス/構造体外のコードに対して読み取り専用のプロパティを作成する場合。

于 2009-11-23T00:14:35.867 に答える
6

変数を設定または取得するときに実行する必要があるコードがある場合、または将来そのようなコードを追加する必要が生じた場合に API に互換性のない変更がある場合は、プロパティがベスト プラクティスです。

後者の節があるため、互換性のない変更を必要とする言語でアクセサーを「プリエンプティブに」使用することはおそらく理にかなっています (Java のgetThis/setThis規則が最もよく知られている例です)。

しかし、API (C#、Ruby、Python など) に互換性のない変更を加えることなく、パブリック変数からプロパティに、またはその逆に切り替えることができる言語の場合、パブリック アクセサー (getterおよびセッター) プライベート変数との間でコピーする以外は何もしません。コンパイラがそれらを最適化できると確信している場合でも、そのようなボイラープレートアクセサーはソースを無用に肥大化させ、そのような言語を作るものの一部である重要な設計機能を無駄にしますいいもの;-)

于 2009-11-23T00:20:41.757 に答える
4

頭のてっぺんから、パブリック フィールドを使用する場所を 2 つ思いつくことができます

  1. アセンブリのコンシューマーに定数または読み取り専用の値を公開する
  2. インフラストラクチャの一部によって強制されている場所 (Workflow Foundation など)
于 2009-11-23T00:16:08.733 に答える
0

まだ言及されていない2つの理由:

  1. フィールドは、refパラメーターとしてメソッドに直接渡すことができます。たとえば、スレッドセーフな方法でフィールドに対して `Interlocked.Increment`を呼び出すことができます(フィールドの他のユーザーも` Interlocked`ルーチンを使用してアクセスする場合)。プロパティをローカル変数にコピーし、その変数を参照で渡してから、変数をプロパティにコピーして戻すと、異なるセマンティクスが生成されます。
  2. 構造タイプのフィールドは、構造タイプのプロパティよりも効率的にアクセスおよび操作できます。実際、可変または大きな構造に関連する「問題」と非効率性の多くは、プロパティが変数のふりをしているという事実に起因していますが、実際にはそうではありません。

これは、フィールドではなくプロパティとして物事を公開することに利点がないという意味ではありませんが、フィールドには明確な利点があります。

于 2012-05-01T16:33:34.130 に答える
0

フィールドがプロパティとは異なる方法で扱われる場合があります。標準のシリアライゼーション フォーマッタ (BinaryFormatter および SoapFormatter) はフィールドをシリアライズしますが、プロパティはシリアライズしません。型のシリアル化を制御するためにこれが必要な場合があります。

于 2009-11-23T17:37:18.897 に答える
0

たとえば、属性 id_code を持つクラスがあるとします。

属性がパブリックの場合、この変数に任意のタイプの値を設定できます。

この id_code を非公開に設定し、それを設定するメソッドを作成すると、id_code の形式に関するルールを作成できます。したがって、方法は次のとおりです。

public setIdCode(String id) {
    my_attribute_id_code = "000"+id;
}

これは最初の簡単な例です。

于 2009-11-23T00:15:18.737 に答える
0

はい。たとえば、フィールドを保護としてマークすると、オブジェクト指向の哲学を概念的に維持している派生クラスによって直接使用できるようになります。

ただし、一般的には、あなたは正しいです。一般に、クラスのフィールドをプライベートとしてマークし、必要なフィールドをプロパティとして公開することをお勧めします。これにより、カプセル化、フィールドの検証、コードのメンテナンスなどが容易になります。

于 2009-11-23T00:18:52.517 に答える
-2

あなたの財産Statusがその性質のものであると言う場合:
public int Status {get; set;}

一部の人々は単に使用するかもしれません:
public int Status;

于 2009-11-23T00:20:34.073 に答える