web-dev-qa-db-ja.com

デフォルトで内部または公開の可視性を使用する必要がありますか?

私はかなり新しいC#および.Net開発者です。私は最近、C#を使用してMMC snapinを作成しました。特に、組織内の他の開発者から、それがどれほど難しいかについて多くのホラーストーリーを聞いた後、その簡単さに満足しました。 C++で。

スナップインを実行するためにランタイムで必要とされる場合を除いて、ある時点でプロジェクト全体をほぼ実行し、「public」キーワードのすべてのインスタンスを「internal」にしました。これについてどう思いますか?一般的にクラスとメソッドをパブリックまたは内部にする必要がありますか?

42

私は可能な限りブラックボックスを信じています。プログラマーとして、システムに簡単にドロップして機能させることができる、明確に定義されたブラックボックスが必要です。値を指定し、適切なメソッドを呼び出してから、結果を取得します。

そのために、クラスが機能するために公開する必要のある機能のみを教えてください。

エレベーターを考えてみましょう。床に移動させるには、ボタンを押します。これは、エレベータを目的の階に移動するために必要なすべての機能をアクティブにするブラックボックスへのパブリックインターフェイスです。

36

あなたがしたことはまさにあなたがすべきことです。クラスに可能な限り最小限の可視性を与えます。ほら、本当に完全にやりたいのなら、すべてinternal(最大)を作成して InternalsVisibleTo attribute 。これにより、機能を分離しても、未知の外の世界に公開することはできません。

公開する唯一の理由は、プロジェクトを複数のDLLやEXEにパッケージ化していること、および(何らかの理由で)InternalsVisibleToを使用する必要がないこと、または次のライブラリを作成していることです。サードパーティによる使用。ただし、サードパーティが使用するライブラリであっても、可能な限り「表面積」を減らすようにしてください。利用できるクラスが多いほど、ライブラリが混乱します。

C#では、可能な限り最小限の可視性を使用していることを確認する1つの良い方法は、必要になるまで可視性修飾子を省略しておくことです。 C#のすべては、デフォルトで可能な限り可視性が低くなります。クラスの場合は内部、クラスメンバーと内部クラスの場合はプライベートです。

12
Ryan Lundy

私はあなたが内部のクラスとメンバーの側で誤りを犯すべきだと思います。アイテムの可視性はいつでも上げることができますが、減らすと問題が発生する可能性があります。これは、他の人のためのフレームワークを構築している場合に特に当てはまります。

便利な機能をユーザーから隠さないように注意する必要があります。 .NET BCLには、リフレクションに頼らなければ使用できない便利なメソッドがたくさんあります。ただし、これらの方法を非表示にすることにより、テストおよび保守が必要なものの表面積が減少します。

7
Brownie

顧客に明示的に消費させたくない場合を除いて、クラスをpublicとしてマークすることは避けたいと思います。また、クラスをサポートする準備ができています。

クラスをinternalとしてマークする代わりに、アクセシビリティを空白のままにします。このように、publicは注目に値するものとして目立ちます。 (もちろん、例外はネストされたクラスであり、同じアセンブリ内でも表示されるようにするには、マークを付ける必要があります。)

4
Jay Bazuzi

ほとんどのクラスはinternalである必要がありますが、ほとんどの非プライベートメンバーはpublicである必要があります。

メンバーについて尋ねる必要がある質問は、「クラスがpublicになった場合、メンバーを公開するメンバーにしたいですか?」です。アクセス可能なメンバーがないクラスはあまり使用されないため、答えは通常「はい(つまり、public)」です。 internalメンバーには役割があります。それらは、同じ議会に住む近親者のみを対象とした「裏口アクセス」です。

クラスが内部に残っている場合でも、どちらがフロントドアメンバーでどれがバックドアメンバーであるかを確認するのは良いことです。そして、それを公開に変更した場合、戻ってどれがどれであるかを考える必要はありません。

2
James

それらをできるだけ見えるようにする必要がありますが、上記のMikeが述べたように、これによりUserControlsで問題が発生し、フォームまたは他のUserControlsでこれらのコントロールを使用してVSDesignerを使用します。

したがって、原則として、Designerを使用して追加しないすべてのクラスとUserControlは、必要な場合にのみ表示されます。デザイナで使用するUserControlを作成している場合(同じアセンブリ内にある場合でも)、UserControlクラス、そのデフォルトコンストラクタ、およびプロパティとイベントがデザイナに対して公開されていることを確認する必要があります。それを操作します。

最近、UserControl MyControlがコンストラクターとともに内部としてマークされたため、デザイナーがthis.myControl = new MyControl()行をInitializeComponent()メソッドから削除し続けるという問題が発生しました。

内部としてマークされていても、Designerに追加するためにツールボックスに表示されるため、Microsoftはパブリックコンストラクターでパブリックコントロールのみを表示する必要があるか、内部コントロールで機能するようにする必要があるため、これは本当にバグだと思います。上手。

1

内部クラスの使用に関する問題可能な限り見つけました。そのタイプ(またはパラメータータイプまたは戻り値のタイプ)のメソッド、プロパティ、フィールドなどを内部よりも目立たせることはできません。これにより、内部のコンストラクターとプロパティが作成されます。これは問題にはならないはずですが、実際のところ、Visual Studioとxamlデザイナーを使用すると、問題が発生します。 偽陽性エラーは設計者によって検出されますメソッドが公開されていないため、ユーザー制御プロパティは設計者に表示されないようです。他の人がすでにそのような問題に陥っているかどうかはわかりません...

1
Mike

他のクラスへの露出はできるだけ少なくする傾向があり、露出する内容とその理由について慎重に検討する必要があります。

1
ColinD

PrivateではなくInternalを使用する必要がある理由はありますか?内部にはアセンブリレベルのスコープがあることに気づきました。言い換えると、内部クラス/メンバーは、マルチクラスアセンブリ内のすべてのクラスにアクセスできます。

他のいくつかの回答が述べているように、実際に内部/保護/パブリックが必要な場合を除いて、一般に可能な限り最高レベルのカプセル化(つまりプライベート)を選択します。

1
Ash

デフォルトでは、クラスはc#で内部として作成されます。内部手段:アクセスは現在のアセンブリに制限されます。

http://msdn.Microsoft.com/en-us/library/0b0thckt.aspx を参照してください

良い記事デフォルトのスコープは内部です: http://www.c-sharpcorner.com/UploadFile/84c85b/default-scope-of-a-C-Sharp-class/

0
user3225726

私はこれまでのところ答えに完全に同意しません。 internalは恐ろしい考えであり、別のAssemblyがタイプを継承できないようにしたり、回避策が必要になった場合に内部タイプを使用したりすることさえできないと思います。

今日、System.Data.DataTableの内部に到達するためにリフレクションを使用する必要があり(すべてのチェックを行わずに、データテーブルを非常に高速に構築する必要があります)、単一のタイプではないため、リフレクションを使用する必要がありました私は利用できました。それらはすべて内部としてマークされました。

0
Peder Rice

それは、それを消費するコードをどれだけ制御できるかによって異なります。私のJava開発では、ゲッターが煩わしいため、デフォルトですべてのものを公開ファイナルにします。ただし、コードベース内のすべてのものをいつでも変更できるという贅沢もあります。以前は、コードをコンシューマーにリリースする必要があったとき、私は常にプライベート変数とゲッターを使用していました。

0
Heath Borders

その特定のクラスの可視性のニーズに最適なものを「デフォルト」で選択しないでください。 Visual Studioで新しいクラスを選択すると、テンプレートは次のように作成されます。

class Class1
{
}

これはプライベートです(スコープが指定されていないため)。クラスのスコープを指定する(またはプライベートのままにする)のはあなた次第です。クラスを公開する理由があるはずです。

0
Ryan Farley

私は物事をできるだけ公開しないのが好きです。プライベート、保護、内部、パブリック:クラス、変数、プロパティ、および関数に、すべてが引き続き機能するために必要な最小限の可視性を提供します。

正当な理由がある場合にのみ、そのチェーンの上位にあるものの可視性を公開します。

0
Matt Blaine