В чем разница между «защищенным» и «защищенным внутренним»?


244

Может кто-нибудь объяснить мне разницу между «защищенными» и «защищенными внутренними» модификаторами в C #? Похоже, они ведут себя одинаково.

Ответы:


402

Модификатор доступа «внутренний защищенный» представляет собой объединение модификаторов «защищенный» и «внутренний».

Из MSDN, Модификаторы доступа (Руководство по программированию в C #) :

защищены :

Доступ к типу или члену возможен только с помощью кода в том же классе или структуре или в классе, производном от этого класса.

внутренний :

Доступ к типу или элементу может получить любой код в той же сборке, но не из другой сборки.

защищенный внутренний :

Доступ к типу или члену может получить любой код в сборке, в которой он объявлен, ИЛИ из производного класса в другой сборке. Доступ из другой сборки должен иметь место в объявлении класса, которое происходит от класса, в котором объявлен защищенный внутренний элемент, и оно должно осуществляться через экземпляр типа производного класса.

Обратите внимание : protected internalозначает « protectedИЛИ internal» (любой класс в той же сборке или любой производный класс - даже если он находится в другой сборке).

... и для полноты:

личное :

Тип или член могут быть доступны только с помощью кода в том же классе или структуре.

общественность :

Доступ к типу или элементу может быть получен из любого другого кода в той же сборке или другой сборке, которая на него ссылается.

частная защита :

Доступ ограничен содержащим классом или типами, производными от содержащего класса в текущей сборке.
( Доступно с C # 7.2 )


2
Могу ли я иметь участника, protected internalтак что он находится protectedв текущей сборке и полностью недоступен снаружи?
Шимми Вайцхандлер

8
Это было бы "Защищено", не так ли?
CAD Bloke

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

1
@Shimmy взгляните на это предложение для будущей версии C # github.com/dotnet/roslyn/blob/features/privateProtected/docs/…
Нейт Кук

@Shimmy По крайней мере, CLR поддерживает концепцию пересечения защищенной и внутренней доступности, а язык C # - нет. C # поддерживает только объединение двух модификаторов доступа.
RBT

89

protected могут использоваться любыми подклассами из любой сборки.

protected internalэто все, что protectedесть, плюс все, что находится в одной сборке, может получить к нему доступ.

Важно отметить, что это не означает «подклассы в одной сборке» - это объединение двух, а не пересечение.


3
Просто к сведению читателей, что CLR также поддерживает концепцию пересечения защищенной и внутренней доступности, но C # этого не поддерживает. C # поддерживает только объединение двух, как упомянуто в этом посте.
RBT

1
Еще один FYI для читателей, «подклассы в той же сборке» могут быть достигнуты с помощью private protectedмодификатора доступа, который был представлен в C # 7.2
LordWilmore

52

- Обновить ответ 2019 -

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

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


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

23

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

Защищено - доступно для унаследованных классов, в противном случае приватное

внутренняя - общедоступная только для классов внутри сборки, в противном случае частная.

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


1
Я бы использовал ИЛИ, чтобы выразить это, потому что это или не то и другое должно быть правдой.
Брайан Расмуссен

Я не полностью согласен с частью «для изменения поведения базового класса» в описании «защищен». Я бы сказал, что здесь вы используете «virtual» (в базовом классе) и «override» (в производном классе).
M4N

Есть ли способ отметить участника как protectedAND internal?
Шимми Вайцхандлер

@ Шимми: да protected internal.
Абатищев

1
@ Шимми два года спустя, и да. Теперь есть способ в C # 7.2. Это называется private protected docs.microsoft.com/en-us/dotnet/csharp/language-reference/…
Паули Остеро

10

По-прежнему существует большая путаница в понимании области действия «защищенных внутренних» методов доступа, хотя у большинства это определение определено правильно. Это помогло мне понять путаницу между «защищенным» и «защищенным внутренним»:

публика действительно публична внутри и вне собрания ( публичный внутренний / публичный внешний )

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

private - это действительно private внутри и вне сборки ( private internal / private external ) (не разрешено в классах верхнего уровня)

внутренняя действительно общедоступна внутри сборки, но исключена вне сборки, как частная ( общедоступная внутренняя / исключенная внешняя )

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

Как вы можете видеть, защищенный внутренний очень странный зверь. Не интуитивно понятно

Теперь возникает вопрос, почему Microsoft не создала ( защищенное внутреннее / исключенное внешнее ) или я полагаю, что-то вроде «частной защиты» или «внутренней защиты»? ржунимагу. Кажется неполным?

К путанице добавляется тот факт, что вы можете вкладывать открытые или защищенные внутренние вложенные элементы внутри защищенного, внутреннего или закрытого типов. Зачем вам доступ к вложенному «защищенному внутреннему» внутри внутреннего класса, который исключает внешний доступ к сборке?

Microsoft говорит, что такие вложенные типы ограничены областью родительских типов, но это не то, что говорит компилятор. Вы можете скомпилировать защищенные внутренние компоненты внутри внутренних классов, которые должны ограничивать область действия только сборкой.

Для меня это похоже на неполный дизайн. Они должны были упростить область действия всех типов до системы, которая четко учитывает наследование, а также безопасность и иерархию вложенных типов. Это сделало бы совместное использование объектов чрезвычайно интуитивным и детализированным, а не открыло бы доступность типов и членов на основе неполной системы определения объема.


1
Закрытая защита теперь добавлена ​​в C # 7.2, который в основном является внутренним И защищенным.
Паули Остеро

7

защищенный : переменная или метод будут доступны только дочерним классам (в любой сборке)

защищенный внутренний : доступен дочерним классам в любой сборке и всем классам в одной сборке


3

Я зачитал очень четкие определения этих терминов.

Защищенный: доступ ограничен определением класса и любым классом, который наследуется от класса. Доступ к типу или члену возможен только с помощью кода в том же классе или структуре или в классе, производном от этого класса.

Внутренний: доступ ограничен только классами, определенными в текущей сборке проекта. Тип или член могут быть доступны только с помощью кода в том же классе.

Protected-Internal: доступ ограничен текущей сборкой или типами, производными от содержащего класса.


1

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

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

Означает, что класс, находящийся вне сборки, может использовать защищенный член другой сборки только унаследованным этим классом.

Мы можем открыть элемент Protected вне сборки, унаследовав этот класс, и использовать его только в производном классе.

Примечание. Защищенные члены недоступны при использовании объекта в производном классе.

Внутренний член

Внутренний член класса доступен или доступ к сборке либо создает объект, либо в производном классе, либо вы можете сказать, что он доступен для всех классов в сборке.

Примечание. Внутренние элементы не доступны вне сборки ни при создании объекта, ни в производном классе.

Защищенный Внутренний

Модификатор защищенного внутреннего доступа - комбинация Защищенный или Внутренний.

Защищенный внутренний элемент может быть доступен во всей сборке, в которой он объявил либо создание объекта, либо наследование этого класса. И может быть доступен вне сборки только в производном классе.

Примечание. Защищенный внутренний элемент работает как внутренний внутри той же сборки и работает как защищенный за пределами сборки.


1

public - члены (функции и переменные), объявленные как public, могут быть доступны из любого места.

private - к закрытым членам нельзя получить доступ за пределами класса. Это спецификатор доступа по умолчанию для члена, т.е. если вы не укажете спецификатор доступа для члена (переменная или функция), он будет считаться закрытым. Следовательно, строка PhoneNumber; эквивалентно частной строке PhoneNumber.

protected - Защищенные члены могут быть доступны только из дочерних классов.

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

защищенный внутренний - к нему можно получить доступ как в той же сборке, так и в производном классе.


0

Защищенные внутренние лучшие наборы, когда вы хотите, чтобы элемент или тип использовались в производном классе из другой сборки, в то же время просто хотите использовать элемент или тип в родительской сборке, не наследуя класс, в котором он объявлен. Также, если вы хотите использовать только член или тип без производных от другого класса, в той же сборке вы можете использовать только внутренний.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.