Яка різниця між "захищеним" та "захищеним внутрішнім"?


244

Може хтось, будь ласка, розробив мені різницю між захищеними та захищеними внутрішніми модифікаторами в C #? Схоже, вони поводяться однаково.

Відповіді:


402

"Захищений внутрішній" модифікатор доступу є об'єднанням "захищених" і "внутрішніх" модифікаторів.

З MSDN, Модифікатори доступу (Посібник з програмування C #) :

захищено :

Доступ до типу або члена можна отримати лише за допомогою коду того ж класу або структури, або в класі, який є похідним від цього класу.

внутрішній :

Тип або член може отримати доступ будь-яким кодом у тій же збірці, але не з іншої збірки.

захищений внутрішній :

Тип або член можна отримати за допомогою будь-якого коду в складі, в якому він оголошений, АБО з всередині похідного класу в іншому складі. Доступ з іншої збірки повинен мати місце в оголошенні класу, що походить від класу, в якому оголошено захищений внутрішній елемент, і має відбуватися через екземпляр похідного типу класу.

Зауважте, що : protected internalозначає " protectedАБО internal" (будь-який клас в одній збірці або будь-який похідний клас - навіть якщо він знаходиться в іншій збірці).

... і для повноти:

приватний :

Доступ до типу або члена можна отримати лише за допомогою коду в одному класі або структурі.

загальнодоступний :

Тип або член може отримати доступ будь-яким іншим кодом у тій же збірці або іншій збірці, на яку посилається.

приватний захищений :

Доступ обмежений класом, що містить або типом, отриманим із класу, що містить, у межах поточної збірки.
( Доступно з C # 7.2 )


2
Чи можу я мати члена, protected internalщоб він знаходився protectedв поточній асамблеї і повністю був недоступний зовні?
Шиммі Вайцхандлер

8
Це було б "Захищено", чи не так?
CAD заблокували

2
@Shimmy: у вас може бути внутрішній клас із захищеними методами . Але тоді весь клас буде недоступний із зовнішніх зборів.
M4N

1
@Shimmy подивіться на цю пропозицію щодо майбутньої версії C # github.com/dotnet/roslyn/blob/features/privateProtected/docs/…
Nate Cook

@Shimmy Принаймні CLR підтримує концепцію перетину захищеної та внутрішньої доступності, але мова C # не робить. C # підтримує лише об'єднання двох модифікаторів доступу.
RBT

89

protected може використовуватися будь-якими підкласами з будь-якої збірки.

protected internalце все, що protectedє, а також все, що в тій же збірці може отримати доступ до нього.

Важливо, що це не означає "підкласи в одній збірці" - це об'єднання двох, а не перетин.


3
Просто FYI для читачів, що CLR підтримує концепцію перетину захищеної та внутрішньої доступності, але C # не підтримує цього. C # підтримує лише об'єднання двох, як згадується у цій публікації.
RBT

1
Ще один FYI для читачів, "підкласи в одній збірці" можна досягти за допомогою private protectedмодифікатора доступу, який був представлений в C # 7.2
LordWilmore

52

- Оновити відповідь 2019 -

Ви можете знайти різницю нижче доступності на основі таблиці, так,

введіть тут опис зображення


4
Прекрасна відповідь, вона дуже чітко повідомляє про відмінності між кожним модифікатором доступу.
e_i_pi

23

На практиці про методи:

захищені - доступні для успадкованих класів, інакше приватні.

внутрішній - загальнодоступний лише для занять всередині зборів, інакше приватний.

внутрішні захищені - означає захищені чи внутрішні - методи стають доступними для успадкованих класів та для будь-яких класів всередині збірки.


1
Я б використав АБО, щоб висловити цю причину, чи це не те, що має бути правдою.
Брайан Расмуссен

Я не повністю згоден з частиною "для зміни поведінки базового класу" в описі "захищеної". Я б сказав, що тут ви використовуєте "віртуальний" (для базового класу) і "переопределення" (для похідного класу).
M4N

Чи є спосіб позначити члена як protectedІ internal?
Шиммі Вайцхандлер

@Shimmy: так , protected internal.
абатищев

1
@Shimmy через два роки, і так. Тепер є шлях у C # 7.2. Його називають private protected docs.microsoft.com/en-us/dotnet/csharp/language-reference/…
Pauli Østerø

10

Існує ще багато плутанини в розумінні сфери "захищених внутрішніх" аксесуарів, хоча більшість мають визначення визначено правильно. Це допомогло мені зрозуміти плутанину між "захищеним" та "захищеним внутрішнім":

громадськість є дійсно публічною всередині та поза межами асамблеї ( громадські внутрішні / громадські зовнішні )

захищений дійсно захищений всередині і зовні збірки ( захищений внутрішній / захищений зовнішній ) (заборонено для класів верхнього рівня)

private - це дійсно приватне всередині і поза складом ( приватне внутрішнє / приватне зовнішнє ) (не допускається для класів вищого рівня)

внутрішній дійсно є загальнодоступним всередині зборів, але виключається за межами асамблеї, як приватний ( публічний внутрішній / виключається зовнішній )

захищений внутрішній дійсно є загальнодоступним всередині зборів, але захищений поза межами зборів ( загальнодоступний внутрішній / захищений зовнішній ) (не допускається для класів вищого рівня)

Як ви бачите захищений внутрішній - це дуже дивний звір. Не інтуїтивно зрозумілий.

Тепер це виникає питання, чому Microsoft не створив ( захищений внутрішній / виключений зовнішній ), або я здогадуюсь про якийсь "приватний захищений" або "внутрішній захищений"? Лол. Здається неповним?

До плутанини додається той факт, що ви можете розміщувати публічні чи захищені внутрішні вкладені члени всередині захищених, внутрішніх чи приватних типів. Чому ви звертаєтесь до вкладеного "захищеного внутрішнього" всередині внутрішнього класу, який виключає доступ із зовнішньої збірки?

Microsoft каже, що такі вкладені типи обмежені сферою застосування їх батьківського типу, але це не те, що говорить компілятор. Ви можете компілювати захищені внутрішні внутрішні класи, які повинні обмежувати область лише монтажем.

Мені це здається незавершеним дизайном. Вони повинні спростити сферу застосування всіх типів до системи, яка чітко враховує спадкування, але також безпеку та ієрархію вкладених типів. Це зробило б обмін об'єктами надзвичайно інтуїтивним та детальним, а не відкриттям доступності типів та членів на основі неповної системи визначення.


1
приватний захищений тепер додано до C # 7.2, який в основному є внутрішнім І захищеним.
Pauli Østerø

7

захищено : змінна чи метод буде доступний лише для дочірніх класів (у будь-якій збірці)

захищений внутрішній : доступний для дочірніх класів у будь-якій збірці та для всіх класів у межах однієї збірки


3

Я прочитав дуже чіткі визначення для цих термінів.

Захищений: доступ обмежений у межах визначення класу та будь-якого класу, який успадковується від класу. Доступ до типу або члена можна отримати лише за допомогою коду в тому ж класі або структурі або в класі, який є похідним від цього класу.

Внутрішній: Доступ обмежується виключно класами, визначеними в рамках поточної збірки проекту. Доступ до типу чи члена можна отримати лише за допомогою коду одного класу.

Захищений-внутрішній: доступ обмежений поточною збіркою або типами, похідними від класу, що містить.


1

Захищений член

Захищений член класу, доступний лише у класі, що міститься (у якому він оголошений), і у похідному класі в межах збірки, а також поза збіркою.

Значить, якщо клас, який знаходиться поза збіркою, може використовувати захищений член іншої збірки, успадковуючи лише цей клас.

Ми можемо викрити захищений член поза збіркою, успадкувавши цей клас і використовувати його лише у похідному класі.

Примітка: Захищені члени недоступні за допомогою об'єкта у похідному класі.

Внутрішній член

Внутрішній член класу є доступним або доступним у межах складання або створює об'єкт, або у похідному класі, або ви можете сказати, що він доступний для всіх класів у складі.

Примітка: Внутрішні члени, недоступні поза складанням, ні за допомогою створення об'єкта, ні у похідному класі

Захищений внутрішній

Модифікатор захищеного внутрішнього доступу є комбінацією Захищений або Внутрішній.

Захищений внутрішній член може бути доступний у всій збірці, в якій він оголосив або створюючи об'єкт, або успадкував цей клас. І може бути доступним поза збіркою лише у похідному класі.

Примітка: Захищений внутрішній член працює як Внутрішній в межах однієї збірки і працює як Захищений для зовнішньої збірки.


1

публічно - до членів (функцій та змінних), оголошених як загальнодоступні, можна отримати доступ з будь-якого місця.

private - приватні члени не можуть бути доступні поза класом. Це специфікатор доступу за замовчуванням для члена, тобто якщо ви не вказали специфікатор доступу для члена (змінної або функції), він буде вважатися приватним. Тому рядок PhoneNumber; еквівалентна приватній рядку PhoneNumber.

захищено - До захищених членів можна отримати доступ лише з дитячих класів.

внутрішній - до нього можна отримати доступ лише в межах однієї збірки.

захищений внутрішній - До нього можна отримати доступ як в одній збірці, так і в похідному класі.


0

Захищені найкращі внутрішні пакети, коли ви хочете, щоб член або тип використовувався у похідному класі з іншої збірки одночасно, просто хочете споживати член або тип у батьківській збірці, не виходячи з класу, де він оголошений. Крім того, якщо ви хочете використовувати лише член або тип з походженням, що походять з іншого класу, в тій же збірці ви можете використовувати лише внутрішній.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.