Что означает запланированный «закрытый защищенный» модификатор доступа C #?


133

Как часть документации Roslyn по GitHub, есть страница, которая называется Статус реализации функции языка. , с запланированными языковыми функциями для C # и VB.

Одна особенность, которую я не мог обернуть вокруг себя, была private protectedмодификатор доступа:

private protected string GetId() { … } 

Существует также страница заметок по дизайну языка C # , на которой объясняется множество новых функций, но не эта.

Эрик Липперт сказал в комментарии :

Ваша ошибка в том, что вы считаете модификаторы возрастающими ограничениями. Модификаторы фактически всегда уменьшают ограничения. Помните, что по умолчанию все "личное"; только добавляя модификаторы, вы делаете их менее ограниченными.

В чем смысл private protected? Когда я могу использовать это?


2
Обратите внимание, что информация об этом есть в примечаниях по дизайну языка VB .
— Джесси Гуд

3
Это сопоставление с MethodAttributes.FamANDAssem. C # имеет странное отображение внутренних , он использует (Private | FamANDAssem). И внутренние защищенные карты (Private | Family). Атрибуты CLR странные.
— Ганс Пассант

22
Эта предложенная функция сделает мой комментарий некорректным.
— Эрик Липперт

Команда разработчиков C # опубликовала опрос с предлагаемым альтернативным синтаксисом для этой функции. Некоторые из них интересны, например protected & internal, assembly protectedили proternal(я надеюсь, что некоторые из них - шутки). Также есть ветка для обсуждения с некоторыми полезными идеями.
— Коби

1
Функция теперь помечена как удаленная в статусе реализации языковой функции! Лично мне нравится идея этого уровня доступа, и я думаю, что это полезная функция. Я хочу использовать защищенный, чтобы сохранить мой код в соответствии с дизайном класса, но я не хочу, чтобы другие писали хакерские подклассы, которые получают доступ к этим членам. ИМО лучшее решение было бы, если бы мы могли написать protected | internalиprotected & internal
— Феликс Кейл

Ответы:


98

Согласно « Professional C # 2008 » Де Билла Эвджена и Джея Глинна, страница 1699:

частная защита - «только производные типы в текущей сборке»

C ++ / CLI имеет аналогичную функцию - определение и использование классов и структур (C ++ / CLI)> Видимость членов :

private protected-или- protected private- Участник защищен внутри сборки, но приватен вне сборки.


72
Так что это «защищенный и внутренний» вместо «защищенный или внутренний»?
— user541686

2
Будет ли теперь возможность иметь член, который доступен производным классам, принимать или возвращать объекты internalтипа, не требуя, чтобы член сам подвергался воздействию всего в сборке?
— суперкат

Спасибо! Я не думал об этом. У меня есть случаи, когда я бы использовал этот модификатор и вернулся к нему internal.
— Коби

3
Существование этого предложения / функции, кажется, предполагает, что internalвидимость (связанная с тем, где определен класс) действительно ортогональна public/ protected/ privateвидимости (связана с наследованием) и что, возможно, internalдолжен быть ее собственный модификатор, отдельный от public/ protected/ private.
— jpmc26

1
@jww - Я не очень знаком с Java, но насколько я знаю packageв Java, это больше похоже на пространство имен в C #.
— Гогуц

187

Вот все модификаторы доступа на диаграммах Венна, от более ограниченных до более беспорядочных:

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

private protected: - добавлено в C # 7.2
введите описание изображения здесь

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

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

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

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


3
Исходное изображение: Access Modifiers.pdn . Я использовал точно названный Paint.Net .
— Коби

9
Где были эти диаграммы всю мою (C #) жизнь? Они превосходны - спасибо!
— Джон Петерсон

28

Это просто для того, чтобы предоставить график (созданный с помощью http://ashitani.jp/gv/ ) различных уровней доступности (изображения не помещаются в комментариях).

орграф диаграмма уровней доступа C #

Каждая стрелка означает «является более строгим, чем».

Имена CLR являются Private, FamilyANDAssembly, Assembly, Family, FamilyORAssembly, Public.


Гораздо позже редактировать: оказалось, что этот хороший новый уровень доступа (с очень плохим именем) в конечном итоге не был включен в C # 6.0. Это поддерживается только из C # 7.2 (и я вижу, вы обновили свой вопрос "теги").


Это может быть только я, но стрелки, кажется, движутся в направлении «менее ограничительного, чем».
— Acarlon

4
@acarlon Да, поэтому a → bна диаграмме означает « aболее ограничивающий, чем b», поэтому вы можете «прочитать» стрелку как «более ограничивающий, чем» (это я и пытался объяснить), поэтому стрелка указывает на наименее ограничивающий » направление». Кстати, противоположное соглашение для стрелок могло быть таким же хорошим, но мне пришлось выбрать одно соглашение.
— Джеппе Стиг Нильсен

10

Это всего лишь предположение, но по названию вы можете догадаться, что это более ограниченная версия protected(или более расслабленная версия, privateесли хотите). И единственный разумный вариант - ограничение protectedповедения сборкой.

Возможное использование: тогда вы хотите иметь protectedдля внутренней реализации, но не для внешнего использования (и вы не хотите закрывать класс).

PS Он всегда существовал в CLR, но не в C # . Это комбинация protected и internal , цитата:

CLR также поддерживает тип доступа «Семья и сборка». Это означает, что метод доступен из объявленного типа, вложенного и производного типов, но только если они объявлены в одной сборке. Ну, очевидно, команда C # не думала об этом как о очень полезной функции, поэтому она не поддерживается на этом языке.


+1 за комментарий CLR - я трачу так много времени на C # и так мало на других языках .NET в эти дни, что я иногда забываю, что это не одно и то же.
— Brichins

@DarrelHoffman спасибо, что заметили! Я немного перепутал здесь свои мысли)
— Петр Абдулин

5

«Может быть» видно только подклассам, которые находятся в одной сборке. Это делает это немного ограниченным, чем protected.


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