1

重複の可能性:
パブリック データ メンバーとゲッター、セッター

プロパティや getter および setter メソッドの代わりにパブリック フィールドを使用する必要があるのはどのような場合ですか (プロパティがサポートされていない場合)。それらの使用が推奨されている正確な場所は何ですか? また、推奨されていない場合、言語機能としてまだ許可されているのはなぜですか? 結局のところ、それらは、getter と setter が許可され奨励されているカプセル化のオブジェクト指向の原則を破っています。

4

6 に答える 6

4

public にする必要がある定数がある場合は、getter プロパティを作成する代わりに、それを public フィールドにすることもできます。

それとは別に、優れた OOP 原則に関する限り、私はその必要性を感じません。

柔軟性が必要な場合があるため、それらは存在し、許可されています。

于 2010-08-17T08:49:56.027 に答える
2

それを言うのは難しいですが、私の意見では、パブリック フィールドは構造体を使用する場合にのみ有効です。

struct Simple
{
    public int Position;
    public bool Exists;
    public double LastValue;
};

しかし、さまざまな人がさまざまな考えを持っています:

http://kristofverbiest.blogspot.com/2007/02/public-fields-and-properties-are-not.html

http://blogs.msdn.com/b/ericgu/archive/2007/02/01/properties-vs-public-fields-redux.aspx

http://www.markhneedham.com/blog/2009/02/04/c-public-fields-vs-automatic-properties/

于 2010-08-17T08:58:45.267 に答える
1

コンパイラが getter と setter の呼び出しを最適化しない場合、プロパティへのアクセスは、フィールド (コール スタック) の読み取りと書き込みよりもコストがかかる可能性があります。これは、非常に多くの呼び出しを実行する場合に関連する可能性があります。

しかし、正直なところ、これが真実である言語を私は知りません。少なくとも .NET と Java の両方で、これは適切に最適化されています。

設計の観点から、フィールドの使用が推奨されるケースはわかりません...

乾杯マティアス

于 2010-08-17T08:52:37.243 に答える
1

まず、なぜアクセサー (ゲッター/セッター) が必要なのかという質問を見てみましょう。新しい値を割り当てる/値を読み取るときに、動作をオーバーライドできるようにする必要があります。キャッシングを追加したり、プロパティの代わりに計算値を返したりすることが必要になる場合があります。

私はいつもこの振る舞いをしたいので、あなたの質問を形成することができますか? これがまったく役に立たないケースを考えることができます: 構造体 ( structC で s だったもの)。Collectionに挿入される複数の値をラップするパラメーター オブジェクトまたはクラスを渡すことは、実際にはアクセサーを必要としない場合です。オブジェクトは単なる変数のコンテナーです。

于 2010-08-17T08:59:59.310 に答える
1

public フィールドの代わりに get を使用する唯一の理由 (*) があります: 遅延評価です。つまり、必要な値がデータベースに格納されているか、計算に時間がかかる可能性があり、起動時にプログラムで初期化するのではなく、必要な場合にのみ初期化する必要があります。

public フィールドの代わりに set を使用する唯一の理由 (*) があります: 他のフィールドの変更です。つまり、ターゲット フィールドの値が変更されたときに、他のフィールドの値を変更します。

すべてのフィールドで get と set の使用を強制することはYAGNIの原則に反します。

オブジェクトからフィールドの値を公開したい場合は、それを公開してください! 4 つの独立したフィールドを持つオブジェクトを作成し、それらすべてが get/set またはプロパティ アクセスを使用することを義務付けるのはまったく無意味です。

*: データ型の変更の可能性など、その他の理由は無意味です。実際、a = o.get_value()の代わりにを使用するa = o.value場合、 が返す型を変更する場合は、 の型get_value()を変更した場合と同様に、使用するたびに変更する必要がありvalueます。

于 2010-08-17T09:08:11.597 に答える
0

主な理由は、OOP のカプセル化とは関係なく (そうであるとよく言われますが)、すべてがバージョン管理に関係しています。

実際、OOP の立場から、カプセル化の欠如は、カプセル化のふりをしてそれを吹き飛ばすものよりも明確であるため、フィールドは「ブラインド」プロパティよりも優れていると主張できます。カプセル化が重要な場合は、カプセル化がない場合に確認することをお勧めします。

Foo というプロパティは、外部からは Foo という public フィールドと同じようには扱われません。一部の言語では、これは明示的 (その言語はプロパティを直接サポートしていないため、getFoo と setFoo があります) であり、一部の言語では暗黙的です (C# と VB.NET はプロパティを直接サポートしていますが、バイナリ互換ではありません)。フィールドとフィールドを使用するようにコンパイルされたコードは、プロパティに変更された場合に壊れます。その逆も同様です)。

Foo が「ブラインド」セットを実行して基になるフィールドを書き込むだけの場合、現在、フィールドを公開することよりもカプセル化の利点はありません。

ただし、後で無効な値を防ぐためにカプセル化を利用する必要がある場合 (無効な値は常に防止する必要がありますが、最初にクラスを作成したときに無効な場所に気付かなかったり、「有効」が変更された可能性があります)スコープの変更)、メモ化された評価をラップする、オブジェクト内の他の変更をトリガーする、変更時イベントをトリガーする、高価な不必要な同等のセットを防ぐなどの場合、実行中のコードを壊さずにその変更を行うことはできません。

クラスが問題のコンポーネントの内部にある場合、これは問題ではありません。フィールドが一般的な YAGNI 原則の下で適切に読み取れる場合は、フィールドを使用すると言えます。ただし、YAGNI はコンポーネントの境界を越えてうまく動作しません (コンポーネントが今日動作する必要がある場合、私のコンポーネントが依存しているコンポーネントを変更した後、明日動作する必要があることは確かです) プロパティを事前に使用することは理にかなっています。

于 2010-08-17T09:21:41.580 に答える