内部クラスのパブリックメソッドと内部メソッド


82
internal class Foo
{
  public void Fee()
  {
    Debug.WriteLine("Fee");
  }

  internal void Fi()
  {
    Debug.WriteLine("Fi");
  }
}

クラス全体がすでに内部にあるので、Fee()とFi()は等しくアクセス可能だと思います。私は何かを見落としていますか?このような場合、メソッドにパブリックまたは内部を選択する理由はありますか?


2
@EricLippertは今日彼の意見をブログに書きました。 ericlippert.com/2014/09/15/internal-or-public/#more-2353
ScottS

回答:


97

internal class Foo宣言は、アクセシビリティのオーバーライドしますpublic void Fee()効果的に、それは内部作り、メソッドを。

この場合、メソッドでinternalとpublicを使用しても同じ効果があります。このような場合にパブリックメソッドと内部メソッドを選択する唯一の理由は、将来のバージョンでパブリッククラスへの移行を容易にするためです。


36

ここで答えに欠けているのは、なぜこれを行うのかということだけです。

一部のライブラリには、ライブラリの利用者が触れることを意図していないクラスがたくさんありますが、パブリックとしてマークされたインターフェイスを継承する必要があります。たとえば、IComparerインターフェイスを継承するクラスを持つライブラリがありますが、それは内部でのみ使用され、ライブラリのパブリックな側面を乱雑にしたくありません。実装されたCompare関数を内部としてマークすると、コンパイラは、インターフェイスIComparerを実装していないと文句を言います。

では、どうすればインターフェイスを正常に実装し、同時にライブラリのパブリックな側面からインターフェイスにアクセスできないようにすることができますか?クラスを内部としてマークしますが、実装された関数はパブリックとしてマークします。


30

実際、リフレクションを使用している場合は大きな違いがあります。特に、Silverlightは、アクセスできたとしても、リフレクションを介して内部メソッドにアクセスしようとすると、非常に混乱する可能性があります。通常の.NETでは機能しますが、Silverlightでコードを機能させるためにメソッドを公開する必要がある場合があります。

通常の.NETの部分的な信頼でも同じことがわかるかもしれません。


3
これらは私がいつも興味を持っている種類の汚い詳細です。しかし、一般的に誰かが私のクラスの隠されたメンバーにアクセスするためにリフレクションを使用している場合、彼らにとって難しいかどうか心配しません。
ScottS 2009

1
@ ScottS-時々あなたはあなた自身のタイプについて熟考してます-つまり、通常は内部メソッドにアクセスできる場所ですが、突然アクセスできなくなります。
MarcGravell

9

内部クラスにインターフェースを実装させたい場合は、違いが生じます。いくつかのインターフェースの実装であるメソッドは、パブリックでなければなりません。


7

あなたは正しいです、FeeとFiの両方が等しくアクセス可能になります。

CSharp言語仕様3.0から、3.5.2の下で:

プログラムP内のタイプTで宣言されたネストされたメンバーMのアクセシビリティドメインは、次のように定義されます(M自体がタイプである可能性があることに注意してください)。

•宣言されたMのアクセシビリティドメインがパブリックである場合、MのアクセシビリティドメインはTのアクセシビリティドメインです。

したがって、Feeがパブリックとして宣言されている場合でも、Fooと同じようにアクセスできます(つまり、内部)。



1

クラスが内部の場合は、内部メソッドのみを使用します。気が変わってクラスを公開した場合は、テキストを置き換えるだけで完了です。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.