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

Может кто - то пожалуйста , объясните разницу между protected и protected internal модификаторов в C#? Похоже, их поведение идентично.

Ответов (11)

Решение

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

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

защищено :

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

внутренний :

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

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

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

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

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

частный :

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

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

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

частные охраняемые :

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Модификатор доступа «Защищенный внутренний» имеет комбинацию «Защищенный» или «Внутренний».

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

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

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

Подумайте о protected internal применении двух модификаторов доступа ( protected и internal ) к одному и тому же полю, свойству или методу.

В реальном мире представьте, что мы даем людям право посещать музей:

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

И мы можем собрать их таким образом:

Все жители города (внутренние) и все жители города, живущие здесь (охраняемые), имеют право посещать музей ( охраняемые внутренние ).

Мир программирования:

internal : поле доступно везде в сборке (проекте). Это все равно, что сказать, что он находится public в области его проекта (но не может быть доступен за пределами области проекта даже для тех классов вне сборки, которые наследуются от этого класса). Каждый экземпляр этого типа может видеть его в этой сборке (объем проекта).

protected : просто означает, что все производные классы могут видеть его (внутри или вне сборки). Так , например , производные классы могут видеть поле или метод внутри его методов и конструкторов с использованием: base.NameOfProtectedInternal .

Итак, объединив эти два модификатора доступа ( protected internal), вы получите что-то, что может быть общедоступным внутри проекта и может быть замечено теми, кто унаследовал от этого класса внутри своей области видимости.

Их можно записать в internal protected, и смысла не меняет, но писать удобно protected internal.

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

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

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

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

internal действительно общедоступен внутри сборки, но исключен вне сборки, например private ( public internal / excluded external )

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

Как видите, protected internal - очень странный зверь. Не интуитивно понятно.

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

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

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

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

Эта таблица показывает разницу. protected internal то же самое protected, за исключением того, что он также разрешает доступ из других классов в той же сборке.

Сравнение модификаторов C#

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

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

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

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

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

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

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

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

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