「保護された」と「保護された内部」の違いは何ですか?


244

誰かが私にC#の「保護された」修飾子と「保護された内部」修飾子の違いを詳しく説明してもらえますか?彼らは同じように振る舞うようです。

回答:


402

「保護された内部」アクセス修飾子は、「保護された」修飾子と「内部」修飾子の和集合です。

以下からのMSDN、アクセス修飾子(C#プログラミングガイド)

保護

型またはメンバーには、同じクラスまたは構造体のコード、またはそのクラスから派生したクラスのコードによってのみアクセスできます。

内部

タイプまたはメンバーには、同じアセンブリ内の任意のコードからアクセスできますが、別のアセンブリからはアクセスできません。

保護された内部

型またはメンバーには、それが宣言されているアセンブリ内の任意のコード、または別のアセンブリの派生クラス内からアクセスできます。別のアセンブリからのアクセスは、保護された内部要素が宣言されているクラスから派生するクラス宣言内で行われる必要があり、派生クラス型のインスタンスを通じて行われる必要があります。

protected internalは「protectedOR internal」を意味することに注意してください(同じアセンブリの任意のクラス、または派生クラス-別のアセンブリにある場合でも)。

...そして完全を期すために:

プライベート

型またはメンバーには、同じクラスまたは構造体のコードからのみアクセスできます。

公開

タイプまたはメンバーには、同じアセンブリまたはそれを参照する別のアセンブリ内の他のコードからアクセスできます。

プライベート保護

アクセスは、現在のアセンブリ内の包含クラス、または包含クラスから派生したタイプに制限されます。
C#7.2以降で利用可能


2
現在のアセンブリにあり、外部から完全に利用できないprotected internalようにするために、メンバーを持つことがprotectedできますか?
Shimmy Weitzhandler 2015年

8
それは「保護されている」でしょうか?
CADは16年

2
@Shimmy:保護されたメソッドを持つ内部クラスを持つことができます。ただし、その場合、クラス全体が外部アセンブリから使用できなくなります。
M4N 2016年

1
C#の将来のバージョンのためにこの提案を見てみ@Shimmy github.com/dotnet/roslyn/blob/features/privateProtected/docs/...
ネイト・クックに

@Shimmy少なくともCLRは、保護されたアクセシビリティと内部のアクセシビリティの共通部分の概念をサポートしていますが、C#言語はサポートしていません。C#は、2つのアクセス修飾子の和集合のみをサポートします。
RBT

89

protected 任意のアセンブリの任意のサブクラスで使用できます。

protected internalつまりprotected、すべてが同じであり、さらに同じアセンブリ内のすべてがそれにアクセスできます。

重要なのは、「同じアセンブリ内のサブクラス」を意味するのではなく、交差ではなく、2つの結合です。


3
CLRは保護されたアクセシビリティと内部のアクセシビリティの共通部分の概念もサポートしているが、C#はこれをサポートしていないという読者向けの参考情報です。この投稿で述べたように、C#は2つの和集合のみをサポートします。
RBT

1
読者のためのもう1つのFYI、「同じアセンブリ内のサブクラス」はprivate protected、C#7.2で導入されたアクセス修飾子を使用して達成できます
LordWilmore

52

-回答の更新2019-

下の表にあるアクセシビリティの違いを確認できます。

ここに画像の説明を入力してください


4
美しい答え、それは各アクセス修飾子の違いを非常に明確に伝えます。
e_i_pi

23

実際には、メソッドについて:

保護 -継承されたクラスからアクセス可能、それ以外の場合はプライベート。

internal-アセンブリ内のクラスに対してのみパブリック、それ以外の場合はプライベート。

保護された内部 -保護または内部-メソッドは、継承されたクラスおよびアセンブリ内のすべてのクラスからアクセス可能になります。


1
私はORを使用して、その原因が両方とも真ではないことを表します。
ブライアンラスムッセン

「保護されている」の説明の「基本クラスの動作を変更する」という部分に完全に同意しません。これは、「基本」で「仮想」と(派生クラスで)「オーバーライド」を使用する場所だと思います。
M4N 2009

protectedAND としてメンバーをマークする方法はありinternalますか?
Shimmy Weitzhandler 2015年

@シミー:はい、protected internal
abatishchev 2015年

1
@シミーは2年後、そうです。現在、C#7.2に方法があります。その呼ばprivate protected docs.microsoft.com/en-us/dotnet/csharp/language-reference/...
パウリØsterø

10

ほとんどの定義が正しく定義されていますが、「保護された内部」アクセサーの範囲を理解することには、依然として多くの混乱があります。これは、「保護された」と「保護された内部」の混同を理解するのに役立ちました。

publicは、アセンブリの内部と外部で実際にパブリックです(public internal / public external

protectedは、アセンブリの内側と外側で本当に保護されています(protected internal / protected external)(トップレベルのクラスでは許可されていません)

プライベートは、アセンブリの内部と外部で実際にプライベートです(プライベート内部/プライベート外部)(トップレベルのクラスでは許可されていません)

内部は実際にはアセンブリ内部でパブリックですが、プライベートのようにアセンブリの外部で除外されていますパブリック内部/除外外部

保護された内部は、実際にはアセンブリ内でパブリックですが、アセンブリの外部で保護されています(パブリック内部/保護された外部)(トップレベルのクラスでは許可されていません)

ご覧のとおり、内部の保護は非常に奇妙な獣です。直感的ではありません。

これで、なぜMicrosoftが(内部保護/外部除外)を作成しなかったのか、ある種の「プライベート保護」または「内部保護」を作成したのではないかという疑問が生じます。笑。不完全なようです?

混乱に加えて、保護型、内部型、またはプライベート型の内部に、パブリックまたは保護された内部のネストされたメンバーをネストできるという事実があります。外部アセンブリアクセスを除外する内部クラス内のネストされた「保護された内部」にアクセスするのはなぜですか?

Microsoftは、そのようなネストされた型は親の型スコープによって制限されると述べていますが、それはコンパイラが言うことではありません。スコープのみをアセンブリに制限する必要がある内部クラス内の保護された内部をコンパイルできます。

私にとってこれは不完全なデザインのように感じます。継承だけでなく、ネストされた型のセキュリティと階層も明確に考慮するシステムに対して、すべての型のスコープを単純化する必要があります。これにより、不完全なスコープシステムに基づいて型とメンバーのアクセス可能性を発見するのではなく、オブジェクトの共有が非常に直感的できめ細かくなります。


1
プライベート保護は、基本的に内部AND保護されているC#7.2に追加されました。
PauliØsterø2017年

7

protected:変数またはメソッドは、(任意のアセンブリの)子クラスでのみ使用できます

protected internal:任意のアセンブリの子クラスおよび同じアセンブリ内のすべてのクラスで使用できます


3

私はこれらの用語の非常に明確な定義を読みました。

保護:アクセスは、クラス定義およびそのクラスから継承するすべてのクラス内に制限されます。型またはメンバーには、同じクラスまたは構造体のコード、またはそのクラスから派生したクラスのコードによってのみアクセスできます。

内部:アクセスは、現在のプロジェクトアセンブリ内で定義されたクラスのみに限定されます。型またはメンバーには、同じクラスのコードからのみアクセスできます。

Protected-Internal:アクセスは、現在のアセンブリまたは包含クラスから派生したタイプに制限されます。


1

保護されたメンバー

クラスのProtected Memberは、含まれているクラス(宣言されているクラス)とアセンブリ内およびアセンブリ外の派生クラスでのみ使用できます。

アセンブリの外部にあるクラスが、そのクラスのみを継承することにより、他のアセンブリの保護されたメンバーを使用できるかどうかを意味します。

そのクラスを継承することでProtectedメンバーをアセンブリの外部に公開し、派生クラスでのみ使用できます。

注:保護されたメンバーは、派生クラスのオブジェクトを使用してアクセスできません。

内部メンバー

クラスの内部メンバーが使用可能であるか、アセンブリ内でオブジェクトを作成するか、派生クラスでアクセスできるか、またはアセンブリ内のすべてのクラスでアクセスできると言えます。

注:オブジェクト作成または派生クラスを使用して、アセンブリの外部から内部メンバーにアクセスすることはできません。

保護された内部

保護された内部アクセス修飾子は、保護または内部の組み合わせです。

保護された内部メンバーは、オブジェクトの作成を宣言したアセンブリ、またはそのクラスを継承したアセンブリ全体で使用できます。また、アセンブリの外部で、派生クラスにのみアクセスできます。

注:保護された内部メンバーは、同じアセンブリ内で内部として機能し、アセンブリの外部では保護されて機能します。


1

public - publicとして宣言されたメンバー(関数と変数)はどこからでもアクセスできます。

private-クラスの外部からプライベートメンバーにアクセスすることはできません。これは、メンバーのデフォルトのアクセス指定子です。つまり、メンバー(変数または関数)のアクセス指定子を指定しない場合、プライベートと見なされます。したがって、文字列PhoneNumber; プライベート文字列PhoneNumberと同等です。

protected-保護されたメンバーは、子クラスからのみアクセスできます。

内部 -同じアセンブリ内でのみアクセスできます。

保護された内部 -同じアセンブリ内および派生クラス内でアクセスできます。


0

メンバーまたは型を別のアセンブリの派生クラスで使用すると同時に、宣言されているクラスから派生せずに、親アセンブリのメンバーまたは型を使用する場合の保護された内部の最適なスイート。また、別のクラスから派生せずにメンバーまたは型のみを使用する場合は、同じアセンブリで内部のみを使用できます。

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