38

ここで、MSDN for C#の命名規則を読むと、プロパティがパブリックフィールドや保護されたフィールドよりも常に優先されることが示されていることがわかります。パブリックフィールドやプロテクトフィールドは絶対に使用しないでくださいと言われたこともあります。今、私はパブリックフィールドが必要な理由をまだ見つけていないことに同意しますが、保護されたフィールドは本当に悪いですか?

値を取得/設定するときに特定の検証チェックが実行されることを確認する必要があるかどうかはわかりますが、多くの場合、私の意見では余分なオーバーヘッドのように見えます。つまり、baseName、prefixName、suffixNameのフィールドを持つクラスGameItemがあるとします。プロパティ()またはアクセサメソッドの作成とパフォーマンスの低下の両方のオーバーヘッドを負担する必要があるのはなぜですか(C#アプリケーションのすべてのフィールドに対してこれを行うと、特にのような特定の言語PHPまたはパフォーマンスのある特定のアプリケーションはゲームのように重要です)?

4

6 に答える 6

94

保護されたメンバー/フィールドは本当に悪いですか?

いいえ、彼らはずっと悪いです。

メンバーがよりアクセスしやすくなるとすぐに、privateそのメンバーがどのように動作するかについて他のクラスに保証します。フィールドは完全に制御されていないため、フィールドを「公開」すると、クラスと、クラスから継承またはクラスと相互作用するクラスが開かれ、バグのリスクが高くなります。フィールドがいつ変更されるかを知る方法はなく、誰が、または何がフィールドを変更するかを制御する方法もありません。

現在、または将来のある時点で、コードのいずれかが特定の値のフィールドに依存する場合は、期待値でない場合に備えて、有効性チェックとフォールバックロジックを追加する必要があります-使用するすべての場所。代わりにそれをいまいましい財産にすることができたとき、それは膨大な量の無駄な努力です;)

派生クラスと情報を共有する最良の方法は、読み取り専用プロパティです。

protected object MyProperty { get; }

どうしても読み取り/書き込みにする必要がある場合はそうしないでください。本当に、本当に読み取り/書き込みにする必要がある場合は、デザインを再考してください。それでも読み書きが必要な場合は、同僚に謝罪し、二度としないでください:)

多くの開発者は、これは過度に厳格であると信じており、あなたに言うでしょう。そして、あなたがこれほど厳格でなくてもうまくやっていくことができるのは事実です。しかし、このアプローチを取ることは、あなたがただ通り抜けるだけでなく、非常に堅牢なソフトウェアに移行するのに役立ちます。バグの修正に費やす時間がはるかに少なくなります。

そして、パフォーマンスに関する懸念については、そうしないでください。キャリア全体で、ボトルネックがコールスタック自体になるほど速くコードを記述しないことを保証します。

于 2010-07-05T23:25:59.133 に答える
34

OK、反対票を投じてください。

  • まず第一に、プロパティがパフォーマンスを損なうことはありません(プロパティがあまり機能しない場合)。それは他の誰もが言うことです、そして私は同意します。

  • もう1つのポイントは、プロパティにブレークポイントを配置して、取得/設定イベントをキャプチャし、それらがどこから来ているかを確認できるという点で優れていることです。

残りの議論はこのように私を悩ませます:

  • 彼らは「名声による議論」のように聞こえます。MSDNがそれを言っている場合、または誰もが好きな有名な開発者や作者がそれを言っている場合、それはそうであるに違いありません。

  • これらは、データ構造には一貫性のない状態が多数あるという考えに基づいており、さまよったり、それらの状態に置かれたりしないように保護する必要があります。(私には)データ構造は現在の教育では非常に強調されているため、通常はそれらの保護が必要です。はるかに好ましいのは、データ構造を最小化して、データが正規化され、一貫性のない状態にならないようにすることです。次に、クラスのメンバーが変更された場合、それは破損するのではなく、単に変更されます。結局のところ、どういうわけか多くの優れたソフトウェアがCで作成されており、保護の欠如による大きな被害はありませんでした。

  • それらは極端に運ばれる防御的なコーディングに基づいています。これは、他の誰のコードもあなたのものをガチョウにしないと信頼できない世界であなたのクラスが使用されるという考えに基づいています。これが本当の状況があると確信していますが、私はそれらを見たことがありません。私見たのは、必要のない保護を回避し、ひどく複雑すぎて正規化されていないデータ構造の一貫性を守ろうとするために、物事がひどく複雑になった状況です。

于 2010-07-05T23:55:42.523 に答える
6

フィールドとプロパティに関して、パブリックインターフェイスでプロパティを優先する理由は2つ考えられます(保護されているのは、クラス以外の誰かがそれを見ることができるという意味でパブリックでもあります)。

  • プロパティを公開すると、実装を非表示にする方法が提供されます。また、それを使用するコードを変更せずに実装を変更することもできます(たとえば、データがクラスに格納される方法を変更する場合)

  • リフレクションを使用してクラスを操作する多くのツールは、プロパティのみに焦点を当てています(たとえば、シリアル化用の一部のライブラリはこのように機能すると思います)。プロパティを一貫して使用すると、これらの標準の.NETツールを簡単に使用できるようになります。

オーバーヘッドについて:

  • ゲッター/セッターがフィールドの値を読み取る/設定するだけの通常の1行のコードである場合、JITは呼び出しをインライン化できるはずなので、パフォーマンスが過剰になることはありません。

  • 自動的に実装されたプロパティ(C#3.0以降)を使用すると、構文上のオーバーヘッドが大幅に削減されるため、これは問題ではないと思います。

    protected int SomeProperty { get; set; }
    

    実際、これにより、たとえばset保護とget公開を非常に簡単に行うことができるため、フィールドを使用するよりもさらにエレガントになります。

于 2010-07-05T23:27:10.410 に答える
6

パブリックフィールドや保護フィールドは、検証なしで宣言クラスの外部から操作できるため、不適切です。したがって、それらはオブジェクト指向プログラミングのカプセル化の原則を破っていると言えます。

カプセル化を失うと、宣言するクラスのコントラクトが失われます。クラスが意図または期待どおりに動作することを保証することはできません。

プロパティまたはメソッドを使用してフィールドにアクセスすると、カプセル化を維持し、宣言するクラスのコントラクトを実行できます。

于 2010-07-05T23:27:33.610 に答える
0

読み取り専用のプロパティの回答に同意します。しかし、ここで悪魔の代弁者を演じるには、それは本当にあなたが何をしているかに依存します。私は常に公開メンバーと一緒にコードを書いていることを認めてうれしく思います(コメントしたり、ガイドラインに従ったり、手続きをしたりすることもありません)。

しかし、私が仕事をしているとき、それは別の話です。

于 2010-07-05T23:51:01.270 に答える
0

実際には、クラスがデータクラスであるか動作クラスであるかによって異なります。

動作とデータを分離しておく場合は、動作がない限り、データクラスのデータを公開することは問題ありません。

クラスが動作クラスの場合、データを公開しないでください。

于 2010-07-06T10:27:07.727 に答える