web-dev-qa-db-ja.com

内部クラスのパブリックおよび内部メンバー?

わかりました、これは少しばかげた質問かもしれません、そして確かに明白な答えがありますが、私がここで微妙なところを見逃したかどうか私は興味がありました。

publicクラスで宣言されたinternalメンバーとinternalクラスで宣言されたinternalメンバーの可視性/使いやすさの点で違いはありますか?

つまり、

internal class Foo
{
    public void Bar()
    {
    }
}

そして

internal class Foo
{
    internal void Bar()
    {
    }
}

メソッドをpublicおよびvirtualとして宣言し、派生クラスのpublicでオーバーライドした場合、この修飾子を使用する理由は明らかです。しかし、これが唯一の状況ですか...他に何か不足していますか?

66
Noldorin

このケースを考えてみましょう:

public interface IBar { void Bar(); }
internal class C : IBar
{
    public void Bar() { }
}

ここでは、C.Barを内部としてマークすることはできません。 C.BarはD.GetBar()の呼び出し元からアクセスできるため、これを行うとエラーになります。

public class D
{
    public static IBar GetBar() { return new C(); } 
}
53
Eric Lippert

publicクラスの場合、internalメンバーはinternalのままです。

MSDNから

メンバーのアクセシビリティは、それを含む型のアクセシビリティを超えることはできません。たとえば、内部型で宣言されたパブリックメソッドには、内部アクセシビリティのみがあります。

このように考えると、私はpublicプロパティにアクセスします...?見えないクラス? :)

この場合、Ericの回答は非常に重要です。直接ではなく、インターフェースを介して公開されている場合does違いが生じます。あなたが扱っているメンバーとの状況。

38
Nick Craver

WPFでXAMLから使用したときに、これらの2つの間にisの違いがある別の例に直面しました。

XAML:

<Button Tag="{x:Static vm:Foo+Bar.e1}" />

internal enumを含むコードは正常にコンパイルされます。

internal class Foo
{
    internal enum Bar
    {
        e1,
        e2,
    }
}

しかし、意外にもpublicに変更すると、エラーが発生します。

internal class Foo
{
    public enum Bar
    {
        e1,
        e2,
    }
}

最後の例ではコンパイルエラーが発生します。

エラーMC3064:マークアップ内で使用できるのはパブリッククラスまたは内部クラスのみです。 「バー」タイプはパブリックまたは内部ではありません。

残念ながら、この場合のpublicの何が問題なのか説明できません。私の推測は、「WPFがそのように機能するからといって」です。ネストされたクラスの修飾子をinternalに変更するだけで、エラーを取り除くことができます。

2
nevermind

リフレクションに関しては、メンバーがパブリックであるかどうかが重要です。

たとえば、ネストされたプライベートクラスをWPFバインディングに渡すこともでき、バインディングは通常どおりパブリックプロパティに対して機能します。

1
springy76

publicクラスのinternalメンバーは、public基本クラスのpublicメンバーをオーバーライドできるため、間接的に表示される場合は、もう少し公開されます。

1
MaxGuernseyIII