Protected c что это
Все поля, методы и остальные компоненты класса имеют модификаторы доступа . Модификаторы доступа позволяют задать допустимую область видимости для компонентов класса. То есть модификаторы доступа определяют контекст, в котором можно употреблять данную переменную или метод.
В языке C# применяются следующие модификаторы доступа:
private : закрытый или приватный компонент класса или структуры. Приватный компонент доступен только в рамках своего класса или структуры.
private protected : компонент класса доступен из любого места в своем классе или в производных классах, которые определены в той же сборке.
file : добавлен в версии C# 11 и применяется к типам, например, классам и структурам. Класс или структура с такми модификатором доступны только из текущего файла кода.
protected : такой компонент класса доступен из любого места в своем классе или в производных классах. При этом производные классы могут располагаться в других сборках.
internal : компоненты класса или структуры доступен из любого места кода в той же сборке, однако он недоступен для других программ и сборок.
protected internal : совмещает функционал двух модификаторов protected и internal . Такой компонент класса доступен из любого места в текущей сборке и из производных классов, которые могут располагаться в других сборках.
public : публичный, общедоступный компонент класса или структуры. Такой компонент доступен из любого места в коде, а также из других программ и сборок.
Стоит отметить, что эти модификаторы могут применяться как к компонентам класса, так и к компонентам структуры за тем исключением, что структуры не могут использовать модификаторы private protected , protected и protected internal , поскольку структуры не могут быть унаследованы.
Все классы и структуры, определенные напрямую вне других типов (классов и структур) могут иметь только модификаторы public , file или internal .
Мы можем явно задать модификатор доступа, а можем его и не указывать:
Если для компонентов не определен модификатор доступа, то по умолчанию для них применяется модификатор private . Например, в примере выше переменная name неявно будет иметь модификатор private .
Классы и структуры, которые объявлены без модификатора и которые расположены вне других типов, по умолчанию имеют доступ internal , а вложенные классы и структуры, как и остальные компоненты классов/структур имеют модификатор private . Например:
Здесь класс Phone не является вложенным ни в один другой класс/структуру, поэтому неявно имеет модификатор internal . А структура Camera является вложенной, поэтому, как и другие компоненты класса, неявно имеет модификатор private
Модификаторы в рамках текущего проекта
Посмотрим на примере и создадим следующий класс State:
Так как класс State не имеет явного модификатора, по умолчанию он имеет модификатор internal , поэтому он будет доступен из любого места данного проекта, однако не будет доступен из других программ и сборок.
Класс State имеет шесть полей для каждого уровня доступа. Плюс одна переменная без модификатора, которая является закрытой (private) по умолчанию. А также определено семь методов с разными модификаторами, которые выводят значения соответствующих переменных на консоль. Поскольку все модификаторы позволяют использовать компоненты класса внутри данного класса, то и все переменные класса, в том числе закрытые, у нас доступны всем его методам, так как все находятся в контексте класса State.
Теперь посмотрим, как мы сможем использовать переменные класса State в другом классе, который, допустим, будет называться StateConsumer и который расположен в том же проекте :
Таким образом, в классе StateConsumer мы смогли только обратиться к переменным internalVar, protectedInternalVar и publicVar, так как их модификаторы позволяют использовать в данном контексте.
Аналогично дело обстоит и с методами:
Здесь нам оказались доступны только три метода: PrintInternal, PrintProtectedInternal, PrintPublic, которые имееют соответственно модификаторы internal, protected internal, public.
Модификаторы в рамках сборок
Допустим, у нас есть проект (и соответственно сборка) MyLib, в которой определены три класса:
Здесь классы DefaultState и InternalState имеют модификатор internal , поэтому доступны только в текущем проекте.
Класс PublicState модификатором public доступен из других проектов. Однако его метод PrintInternal() доступен только в текущем проекте. Вне текущего проекта доступен только его метод PrintPublic и PrintProtectedInternal() (доступен в другом проекте только в классах-наследниках).
Допустим, мы подключаем сборку этого проекта MyLib в другой проект, где есть класс StateConsumer:
В классе StateConsumer есть доступ только к классу PublicState и его методу PrintPublic , потому что они имеют модификатор public . К остальной функциональности подключенной сборки StateConsumer доступа не имеет.
Благодаря такой системе модификаторов доступа можно скрывать некоторые моменты реализации класса от других частей программы.
Файл как область видимости
C# 11 добавил еще один модификатор видимости — file , который с применяется к классам, структурам, делегатам, перечислениям, интерфейсам. Типы с этим модификаторо могут использоваться только внутри текущего файла кода.
Данный модификатор не может использоваться в паре с другими модификаторами.
Name already in use
docs / docs / csharp / language-reference / keywords / protected.md
- Go to file T
- Go to line L
- Copy path
- Copy permalink
- Open with Desktop
- View raw
- Copy raw contents Copy raw contents
Copy raw contents
Copy raw contents
protected (C# Reference)
The protected keyword is a member access modifier.
[!NOTE] This page covers protected access. The protected keyword is also part of the protected internal and private protected access modifiers.
A protected member is accessible within its class and by derived class instances.
For a comparison of protected with the other access modifiers, see Accessibility Levels.
A protected member of a base class is accessible in a derived class only if the access occurs through the derived class type. For example, consider the following code segment:
The statement a.x = 10 generates an error because it is made within the static method Main, and not an instance of class B.
Struct members cannot be protected because the struct cannot be inherited.
In this example, the class DerivedPoint is derived from Point . Therefore, you can access the protected members of the base class directly from the derived class.
If you change the access levels of x and y to private, the compiler will issue the error messages:
‘Point.y’ is inaccessible due to its protection level.
‘Point.x’ is inaccessible due to its protection level.
C# language specification
For more information, see Declared accessibility in the C# Language Specification. The language specification is the definitive source for C# syntax and usage.
C# protected: How to use it?

C# has several access modifiers that control the visibility of types and members.
The purpose of access modifiers is to prevent the misuse of members that are not ready for public use.
Access modifiers are important for developers because they make code easier to read and write.
One of the most important access modifiers is the protected .
What is protected in C#?
Protected is a keyword that C# uses to make access restriction for class members.
When we mark members as protected, it becomes accessible only in the class where it's defined or inside the derived class.
The protected keyword is used to share functionality that derived classes might find useful.
In C#, we can use protected access modifier in 3 combinations:
- Protected
- Protected internal
- Protected private
Without protected property, derived classes wouldn't be able to access private members.
Protected
The protected access modifier lets you make variables and methods accessible only by code in the same class or struct, or in a derived class.
Protected makes members:
- accessible to all classes that extend the class regardless of the assembly
Protected internal
C# 7.2 added protected internal keyword.
Protected internal makes members:
- accessible to all classes that extend the class
- accessible to all other classes in same assembly
Private protected
Private protected access modifier is more restrictive than either protected or internal.
Private protected makes members:
- accessible ONLY to classes that extend the class AND are in same assembly
You have access to a private protected member only from code that’s in the same assembly and is within a subclass of the member declaration.
When to use protected in C#?
You can use the protected accessibility modifier to help children have access to their parents' properties. This is helpful when you have a base class that many subclasses derive from.
With protected, you can make a common property protected so that it is easy to maintain and reuse common logic.
One of the main benefits of protecting members is that it makes your code more robust and consistent. This helps to reduce the risk of bugs ad spaghetti code because it prevents other classes from modifying these behaviors.
Naming convention
Private, protected, internal, and protected internal fields and properties are named using _camelCase.
That naming convention clarifies that protected members are different root classes, and should not be mistaken for fields or properties.
Accessibility and inheritance
C# has four levels of accessibility and inheritance:
- public — available to all
- private — accessible only from within the type that declared them
- internal — members are available to code defined in the same component
- protected — members are available to code within the type that declared them, and subclasses of that type
C# Protected Vs Private
The main difference between protected and private is that private hides the member from further derivation, while protected allows access in subclasses of its own type.
Example
In this example, derived class SubOrder cannot access the private member tax :
Введение в ООП с примерами на C#. Часть пятая. Всё о модификаторах доступа
В прошлых статьях серии «Введение в ООП» мы рассматривали полиморфизм (а также нюансы использования его на практике), наследование и абстрактные классы. В этой части я постараюсь раскрыть все тонкости использования модификаторов доступа, которые знаю сам. Продолжаем погружаться в ООП!
Что такое модификаторы доступа?
Давайте в этот раз возьмём определение из Википедии (в русской Википедии статьи access modifiers нет, поэтому здесь приводим свой перевод — прим. перев.) :
Модификаторы доступа (или спецификаторы доступа) — ключевые слова в объектно-ориентированных языках, которые задают (внезапно!) параметры доступа для классов, методов и прочих элементов. Модификаторы доступа — специфичная часть языков программирования для облегчения инкапсуляции компонентов.
Модификаторы public, private, protected
Каждый раз, когда мы создаём класс, мы хотим иметь возможность определять, кто и откуда может взаимодействовать с его членами. Иными словами, нам иногда нужно ограничивать доступ к некоторым членам класса. Есть одно простое правило — члены одного класса всегда имеют доступ друг к другу. Если же говорить про доступ извне, то стоит запомнить, что модификатор доступа по умолчанию — private , т.е. все члены класса доступны только изнутри него самого.
Традиционно сразу переходим к практике. Давайте попробуем выполнить следующий код:
Результатом выполнения этого кода будет:
BBB() отмечен как public , соответственно его можно вызывать откуда угодно. Метод AAA() же никак не отмечен, значит, он является приватным. Однако для члена того же класса (ведь AAA() и BBB() принадлежат одному классу, верно?) это не имеет никакого значения.
Теперь попробуем получить доступ к AAA() напрямую:
‘AccessModifiers.Modifiers.AAA()’ is inaccessible due to its protection level
Для внешних вызовов модификатор private — непреодолимая преграда. То же самое можно сказать и о модификаторе protected .
Модификаторы доступа и наследование
Снова попробуем выполнить код:
Запускаем код и видим…
‘AccessModifiers.ModifiersBase.AAA()’ is inaccessible due to its protection level
Приватные члены недоступны даже дочерним классам. Публичные члены доступны всем, это понятно. Модификатор же protected по сути и обозначает, что член доступен только дочерним классам — вызов CCC() в примере выше не вызывает никаких ошибок.
Модификатор Internal для классов
Давайте рассмотрим следующий сценарий: мы создаём в новой библиотеке классов (назовём её AccessModifiersLibrary ) класс ClassA и помечаем его как internal :
Теперь в созданном ранее файле попробуем выполнить:
Compile time error: ‘AccessModifiersLibrary.ClassA’ is inaccessible due to its protection level
Мы встретили эту ошибку из-за спецификатора доступа internal , который обозначает, что ClassA доступен только внутри AccessModifiersLibrary и ниоткуда больше. Впрочем, если мы уберём этот модификатор, ничего не изменится — internal является спецификатором по умолчанию.
Модификаторы для пространств имён
Давайте попробуем сделать с предыдущим кодом следующее:
Конечно, это не скомпилируется:
Compile time error: A namespace declaration cannot have modifiers or attributes
Все пространства имён по умолчанию являются публичными, и мы не можем добавить к их объявлению никаких модификаторов, включая ещё один public .
Приватные классы
Если мы попробуем скомпилировать код, приведённый выше, то получим ошибку:
Compile time error: Elements defined in a namespace cannot be explicitly declared as private, protected, or protected internal
Всё правильно: классы могут быть либо public , либо internal .
Подробнее о модификаторах членов класса
Что будет, если мы захотим назначить члену класса больше одного модификатора доступа?
Будет ошибка компиляции:
Compile time error: More than one protection modifier
А как поведёт себя язык, если мы создадим public метод в internal классе?
Вывод после компиляции:
‘AccessModifiersLibrary.ClassA’ is inaccessible due to its protection level
The type ‘AccessModifiersLibrary.ClassA’ has no constructors defined
‘AccessModifiersLibrary.ClassA’ is inaccessible due to its protection level
‘AccessModifiersLibrary.ClassA’ does not contain a definition for ‘MethodClassA’ and
no extension method ‘MethodClassA’ accepting a first argument of type ‘AccessModifiersLibrary.ClassA’
could be found (are you missing a using directive or an assembly reference?)
Как много ошибок… Дело в том, что какими бы модификаторами не обладали члены internal класса, их всё равно нельзя вызвать оттуда, где не виден сам класс. А что будет, если мы попробуем сделать наоборот — вызвать private или internal метод у public класса?
‘AccessModifiersLibrary.ClassA’ does not contain a definition
for ‘MethodClassA’ and no extension method ‘MethodClassA’ accepting a first argument
of type ‘AccessModifiersLibrary.ClassA’ could be found (are you missing a using directive or an assembly reference?)
Не-а, всё равно не работает. А если изменим модификатор метода на internal ?
‘AccessModifiersLibrary.ClassA’ does not contain a definition for ‘MethodClassA’ and no extension
method ‘MethodClassA’ accepting a first argument of type ‘AccessModifiersLibrary.ClassA’ could be
found (are you missing a using directive or an assembly reference?)
Увы, так делать тоже нельзя.
Модификатор protected internal
Этот код компилируется без ошибок. Модификатор internal proteted (как не слишком сложно догадаться) даёт понять, что метод доступен как для вызовов из того же файла, в котором он объявлен, так и для вызовов из дочерних классов.
Protected поля
Здесь всё будет немного сложнее. Давайте напишем следующий код:
Если мы его запустим, то получим ошибку:
Cannot access protected member ‘AccessModifiers.AAA.a’ via a qualifier of type ‘AccessModifiers.AAA’;
the qualifier must be of type ‘AccessModifiers.BBB’ (or derived from it)
Совершенно неочевидно, правда? Компилятор ругается на строчку aaa.a = 100 из метода MethodBBB . Почему никаких ошибок не вызывает метод MethodAAA понять достаточно просто — поле a объявлено в том же файле, в том же классе, в котором к нему и происходит обращение, это не может быть ошибкой. Почему в классе BBB доступен член bbb.a тоже понятно — модификатор protected прямо разрешает использовать члены родительского класса в дочернем как свои. Почему же вызов aaa.a = 100 из метода MethodBBB под запретом? Пожалуй, это стоит просто запомнить.
(От редакции) Скорее всего, это сделано, чтобы нельзя было делать следующим образом:
Приоритет модификаторов
Compile time error: Inconsistent accessibility: base class ‘AccessModifiers.AAA’ is less accessible than class ‘AccessModifiers.BBB’
К дочернему классу не может быть большего доступа, чем к родительскому. Как вы понимаете, public предоставляет гораздо больший доступ, чем модификатор по умолчанию internal . Причём нельзя делать даже так:
Inconsistent accessibility: return type ‘AccessModifiers.AAA’ is less accessible than method ‘AccessModifiers.BBB.MethodB()’
Inconsistent accessibility: field type ‘AccessModifiers.AAA’ is less accessible than field ‘AccessModifiers.BBB.aaa’
Подведём итоги:
- Модификатор доступа по умолчанию для членов класса — private ;
- Модификатор доступа internal значит, что доступ разрешён только из того же файла;
- У пространств имён нет и не может быть модификаторов доступа (можно считать, что они все public );
- Классы могут иметь только два модификатора доступа — internal (по умолчанию) и public
- Модификатор protected internal значит, что доступ есть как из того же файла, так и из дочерних классов
- Родительский класс не может быть менее доступен, чем дочерний
- Возвращаемое значение метода не может быть менее доступно, чем сам метод
- Поле не может быть более доступно, чем его тип
Работу с константами и sealed классами (которая тоже осуществляется за счёт модификаторов доступа) мы разберём в следующей статье.