誰かがC#の「保護された」修飾子と「保護された内部」修飾子の違いを詳しく教えてもらえますか?彼らは同じように振る舞います。
「保護された内部」アクセス修飾子は、「保護された」修飾子と「内部」修飾子の両方のunionです。
から MSDN、アクセス修飾子(C#プログラミングガイド) :
型またはメンバーにアクセスできるのは、同じクラスまたは構造体のコード、またはそのクラスから派生したクラスのコードのみです。
内部:
型またはメンバーには、同じアセンブリ内の任意のコードからアクセスできますが、別のアセンブリからはアクセスできません。
保護された内部:
型またはメンバーには、別のアセンブリの派生クラス内から、宣言されているアセンブリ内の任意のコードまたはからアクセスできます。別のアセンブリからのアクセスは、保護された内部要素が宣言されているクラスから派生するクラス宣言内で発生する必要があり、派生クラス型のインスタンスを介して発生する必要があります。
注意してください:protected internal
は「protected
OR internal
」を意味します(同じアセンブリ内の任意のクラス、または派生クラス-たとえ別のアセンブリにあります)。
...そして完全を期すために:
型またはメンバーには、同じクラスまたは構造体のコードによってのみアクセスできます。
型またはメンバーには、同じアセンブリまたはそれを参照する別のアセンブリ内の他のコードからアクセスできます。
アクセスは、包含クラスまたは現在のアセンブリ内の包含クラスから派生した型に制限されます。
(C#7.2以降で利用可能)
protected
は、任意のアセンブリの任意のサブクラスで使用できます。
protected internal
は、protected
がすべてであることに加えて、同じアセンブリ内のすべてがアクセスできます。
重要なのは、「同じアセンブリ内のサブクラス」を意味するものではありません-交差ではなく、2つの結合です。
実際には、メソッドについて:
protected-継承されたクラスからアクセス可能、それ以外の場合はプライベート。
内部-アセンブリ内のクラスに対してのみパブリック、それ以外はプライベート。
保護された内部-保護されたまたはを意味します内部-継承されたクラスおよびアセンブリ内のクラスの場合。
「保護された内部」アクセサーの範囲を理解することには依然として多くの混乱がありますが、ほとんどの定義は正しく定義されています。これは、「保護された」と「保護された内部」の混乱を理解するのに役立ちました。
publicは、アセンブリの内外で実際に公開されています(public internal/public external)
protectedは実際にアセンブリの内側と外側で保護されています(protected internal/protected external)(トップレベルのクラスでは許可されていません)
プライベートはアセンブリの内部および外部で本当にプライベートです(プライベート内部/プライベート外部)(トップレベルのクラスでは許可されていません)
内部はアセンブリ内で実際に公開されていますが、プライベートのようにアセンブリ外で除外されています(public internal/exclude external)
保護された内部はアセンブリ内で実際に公開されていますが、アセンブリ外で保護されています(public internal/protected external)(トップレベルのクラスでは許可されていません)
ご覧のとおり、protected internalは非常に奇妙な獣です。直感的ではありません。
それは今、なぜMicrosoftが(保護された内部/除外された外部)を作成しなかったのか、または何らかの種類の「プライベート保護」または「内部保護」を推測しなかったのかという疑問を投げかけますか?笑。不完全なようですか?
混乱に追加されるのは、保護されたタイプ、内部タイプ、またはプライベートタイプ内にパブリックまたは保護された内部ネストメンバーをネストできるという事実です。外部クラスのアクセスを除外する内部クラス内のネストされた「保護された内部」にアクセスするのはなぜですか?
マイクロソフトは、そのようなネストされた型は親の型スコープによって制限されると言いますが、それはコンパイラが言うことではありません。スコープをアセンブリのみに制限する必要がある内部クラス内で、保護された内部をコンパイルできます。
私にはこれは不完全なデザインのように感じます。継承を明確に考慮したシステムにすべてのタイプのスコープを単純化する必要がありますが、ネストされたタイプのセキュリティと階層も必要です。これにより、不完全なスコーピングシステムに基づいて型およびメンバーのアクセシビリティを検出するのではなく、オブジェクトの共有が非常に直感的かつきめ細かくなります。
protected:変数またはメソッドは、子クラス(すべてのアセンブリ内)でのみ使用可能です
保護された内部:アセンブリ内の子クラスで使用可能and同じアセンブリ内のすべてのクラス
これらの用語の非常に明確な定義を読みました。
保護:クラス定義内およびクラスから継承するクラス内にアクセスが制限されます。型またはメンバーにアクセスできるのは、同じクラスまたは構造体のコード、またはそのクラスから派生したクラスのコードのみです。
内部:アクセスは、現在のプロジェクトアセンブリ内で定義されたクラスのみに制限されます。型またはメンバーには、同じクラスのコードによってのみアクセスできます。
Protected-Internal:アクセスは、現在のアセンブリまたは包含クラスから派生したタイプに制限されます。
保護されたメンバー
含まれているクラス(宣言されているクラス)およびアセンブリ内およびアセンブリ外の派生クラスでのみ使用可能なクラスの保護されたメンバー。
アセンブリの外部にあるクラスが、そのクラスのみを継承することにより、他のアセンブリの保護されたメンバーを使用できるかどうかを意味します。
そのクラスを継承し、派生クラスでのみ使用することにより、Protectedメンバーをアセンブリの外部に公開できます。
注:保護されたメンバーは、派生クラスのオブジェクトを使用してアクセスできません。
内部メンバー
クラスの内部メンバーは、オブジェクトを作成するか、派生クラスのいずれかでアセンブリ内で使用可能またはアクセスできます。アセンブリ内のすべてのクラスでアクセス可能であると言うことができます。
注:オブジェクト作成または派生クラスを使用して、アセンブリの外部からアクセスできない内部メンバー。
保護された内部
保護された内部アクセス修飾子は、保護または内部の組み合わせです。
保護された内部メンバーは、オブジェクトの作成またはそのクラスの継承によって宣言されたアセンブリ全体で使用できます。また、派生クラスでのみアセンブリの外部からアクセスできます。
注:保護された内部メンバーは、同じアセンブリ内では内部として機能し、アセンブリ外では保護として機能します。
public-publicとして宣言されたメンバー(関数と変数)はどこからでもアクセスできます。
private-クラスの外部からプライベートメンバーにアクセスすることはできません。これはメンバーのデフォルトのアクセス指定子です。つまり、メンバー(変数または関数)のアクセス指定子を指定しない場合、プライベートと見なされます。したがって、文字列PhoneNumber;プライベート文字列PhoneNumberと同等です。
protected-保護されたメンバーは、子クラスからのみアクセスできます。
内部-同じアセンブリ内でのみアクセスできます。
保護された内部-同じアセンブリ内および派生クラス内でアクセスできます。
メンバーまたは型を別のアセンブリの派生クラスで使用すると同時に、宣言されているクラスから派生せずに親アセンブリのメンバーまたは型を消費する場合の内部ベストスイートを保護します。また、別のクラスから派生せずにメンバーまたはタイプのみを使用する場合は、同じアセンブリで内部のみを使用できます。