Полное руководство по языку программирования С# 14 и платформе .NET 10 / Классы, структуры и пространства имен

Модификаторы доступа

Начальный ⏱ 7 мин чтения 👁 2 🕓 обновлено 11.08.2026

Все поля, методы и остальные компоненты класса имеют модификаторы доступа. Модификаторы доступа позволяют задать допустимую область видимости для компонентов класса. То есть модификаторы доступа определяют контекст, в котором можно употреблять данную переменную или метод.

В языке C# применяются следующие модификаторы доступа:

  • private: закрытый или приватный компонент класса или структуры. Приватный компонент доступен только в рамках своего класса или структуры.

  • private protected: компонент класса доступен из любого места в своем классе или в производных классах, которые определены в той же сборке.

  • file: добавлен в версии C# 11 и применяется к типам, например, классам и структурам. Класс или структура с такми модификатором доступны только из текущего файла кода.

  • protected: такой компонент класса доступен из любого места в своем классе или в производных классах. При этом производные классы могут располагаться в других сборках.

  • internal: компоненты класса или структуры доступен из любого места кода в той же сборке, однако он недоступен для других программ и сборок.

  • protected internal: совмещает функционал двух модификаторов protected и internal. Такой компонент класса доступен из любого места в текущей сборке и из производных классов, которые могут располагаться в других сборках.

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

Стоит отметить, что эти модификаторы могут применяться как к компонентам класса, так и к компонентам структуры за тем исключением, что структуры не могут использовать модификаторы private protected, protected и protected internal, поскольку структуры не могут быть унаследованы.

Все классы и структуры, определенные напрямую вне других типов (классов и структур) могут иметь только модификаторы public, file или internal.

Мы можем явно задать модификатор доступа, а можем его и не указывать:


public class Person
{
	string name;
	public Person(string name) 
	{
		this.name = name;
	}
	public void Print() => Console.WriteLine($"Name: {name}");
}

Если для компонентов не определен модификатор доступа, то по умолчанию для них применяется модификатор private. Например, в примере выше переменная name неявно будет иметь модификатор private.

Классы и структуры, которые объявлены без модификатора и которые расположены вне других типов, по умолчанию имеют доступ internal, а вложенные классы и структуры, как и остальные компоненты классов/структур имеют модификатор private. Например:


class Phone
{
    struct Camera
    {

    }
}

Здесь класс Phone не является вложенным ни в один другой класс/структуру, поэтому неявно имеет модификатор internal. А структура Camera является вложенной, поэтому, как и другие компоненты класса, неявно имеет модификатор private

Модификаторы в рамках текущего проекта

Посмотрим на примере и создадим следующий класс State:


class State
{
    // все равно, что private string defaultVar;
    string defaultVar ="default";
    // поле доступно только из текущего класса
    private string privateVar = "private";
    // доступно из текущего класса и производных классов, которые определены в этом же проекте
    protected private string protectedPrivateVar = "protected private";
    // доступно из текущего класса и производных классов
    protected string protectedVar = "protected";
    // доступно в любом месте текущего проекта
    internal string internalVar = "internal";
    // доступно в любом месте текущего проекта и из классов-наследников в других проектах
    protected internal string protectedInternalVar = "protected internal";
    // доступно в любом месте программы, а также для других программ и сборок
    public string publicVar = "public";

    // по умолчанию имеет модификатор private
    void Print() => Console.WriteLine(defaultVar);

    // метод доступен только из текущего класса
    private void PrintPrivate() => Console.WriteLine(privateVar);

    // доступен из текущего класса и производных классов, которые определены в этом же проекте
    protected private void PrintProtectedPrivate() => Console.WriteLine(protectedPrivateVar);

    // доступен из текущего класса и производных классов
    protected void PrintProtected() => Console.WriteLine(protectedVar);

    // доступен в любом месте текущего проекта
    internal void PrintInternal() => Console.WriteLine(internalVar);

    // доступен в любом месте текущего проекта и из классов-наследников в других проектах
    protected internal void PrintProtectedInternal() => Console.WriteLine(protectedInternalVar);

    // доступен в любом месте программы, а также для других программ и сборок
    public void PrintPublic() => Console.WriteLine(publicVar);
}

Так как класс State не имеет явного модификатора, по умолчанию он имеет модификатор internal, поэтому он будет доступен из любого места данного проекта, однако не будет доступен из других программ и сборок.

Класс State имеет шесть полей для каждого уровня доступа. Плюс одна переменная без модификатора, которая является закрытой (private) по умолчанию. А также определено семь методов с разными модификаторами, которые выводят значения соответствующих переменных на консоль. Поскольку все модификаторы позволяют использовать компоненты класса внутри данного класса, то и все переменные класса, в том числе закрытые, у нас доступны всем его методам, так как все находятся в контексте класса State.

Теперь посмотрим, как мы сможем использовать переменные класса State в другом классе, который, допустим, будет называться StateConsumer и который расположен в том же проекте:


class StateConsumer
{
    public void PrintState()
    {
        State state = new State();

        // обратиться к переменной defaultVar у нас не получится,
        // так как она имеет модификатор private и класс StateConsumer ее не видит
        Console.WriteLine(state.defaultVar); //Ошибка, получить доступ нельзя

        // то же самое относится и к переменной privateVar
        Console.WriteLine(state.privateVar); // Ошибка, получить доступ нельзя

        // обратиться к переменной protectedPrivateVar не получится,
        // так как класс StateConsumer не является классом-наследником класса State
        Console.WriteLine(state.protectedPrivateVar); // Ошибка, получить доступ нельзя

        // обратиться к переменной protectedVar тоже не получится,
        // так как класс StateConsumer не является классом-наследником класса State
        Console.WriteLine(state.protectedVar); // Ошибка, получить доступ нельзя

        // переменная internalVar с модификатором internal доступна из любого места текущего проекта
        // поэтому можно получить или изменить ее значение
        Console.WriteLine(state.internalVar);

        // переменная protectedInternalVar так же доступна из любого места текущего проекта
        Console.WriteLine(state.protectedInternalVar);

        // переменная publicVar общедоступна
        Console.WriteLine(state.publicVar);
    }
}

Таким образом, в классе StateConsumer мы смогли только обратиться к переменным internalVar, protectedInternalVar и publicVar, так как их модификаторы позволяют использовать в данном контексте.

Аналогично дело обстоит и с методами:


class StateConsumer
{
    public void PrintState()
    {
        State state = new State();

        state.Print(); //Ошибка, получить доступ нельзя

        state.PrintPrivate(); // Ошибка, получить доступ нельзя

        state.PrintProtectedPrivate(); // Ошибка, получить доступ нельзя

        state.PrintProtected(); // Ошибка, получить доступ нельзя

        state.PrintInternal();    // норм

        state.PrintProtectedInternal();  // норм

        state.PrintPublic();      // норм
    }
}

Здесь нам оказались доступны только три метода: PrintInternal, PrintProtectedInternal, PrintPublic, которые имееют соответственно модификаторы internal, protected internal, public.

Модификаторы в рамках сборок

Допустим, у нас есть проект (и соответственно сборка) MyLib, в которой определены три класса:


namespace MyLib;
// класс доступен из других сборок
public class PublicState
{
    internal void PrintInternal() => Console.WriteLine("internal");
    protected internal void PrintProtectedInternal() => Console.WriteLine("protected internal");
    public void PrintPublic() => Console.WriteLine("public");

}

// класс доступен только в текущей сборке - по умолчанию internal
class DefaultState { }
// класс доступен только в текущей сборке
internal class InternalState{  }

Здесь классы DefaultState и InternalState имеют модификатор internal, поэтому доступны только в текущем проекте.

Класс PublicState модификатором public доступен из других проектов. Однако его метод PrintInternal() доступен только в текущем проекте. Вне текущего проекта доступен только его метод PrintPublic и PrintProtectedInternal() (доступен в другом проекте только в классах-наследниках).

Допустим, мы подключаем сборку этого проекта MyLib в другой проект, где есть класс StateConsumer:


using MyLib;
class StateConsumer
{
    public void PrintState()
    {
        // Ошибка DefaultState - по умолчанию internal, поэтому нет доступа
        DefaultState defaultState = new DefaultState();
        // Ошибка InternalState - internal, поэтому нет доступа
        InternalState internalState = new InternalState();

        // норм, PublicState - public, доступен из других программ
        PublicState publicState = new PublicState();
        // Ошибка, нет доступа - метод доступен только в свой сборке
        publicState.PrintInternal();
        // Ошибка, нет доступа - StateConsumer НЕ является классом-наследником от класса PublicState,
        // поэтому метод не доступен
        publicState.PrintProtectedInternal();  // нет доступа
        // норм - общедоступный метод
        publicState.PrintPublic();      // норм
    }
}

В классе StateConsumer есть доступ только к классу PublicState и его методу PrintPublic, потому что они имеют модификатор public. К остальной функциональности подключенной сборки StateConsumer доступа не имеет.

Благодаря такой системе модификаторов доступа можно скрывать некоторые моменты реализации класса от других частей программы.

Файл как область видимости

C# 11 был добавлен еще один модификатор видимости - file, который применяется к классам, структурам, делегатам, перечислениям, интерфейсам. Типы с этим модификатором могут использоваться только внутри текущего файла кода.


file class Person
{
}

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

Дополнительные материалы

Проверь себя

📋 Тест по теме «Модификаторы доступа» Тест по теме

Практические задания

Лёгкое Ручная проверка Заполните пропуск в коде (1)
+10 XP

В приведённом ниже фрагменте кода из этого урока пропущено одно слово. Определите его и впишите в поле ответа (без кавычек и пробелов).

public class _____
{
	string name;
	public Person(string name) 
	{
		this.name = name;
	}
	public void Print() => Console.WriteLine($"Name: {name}");
}
Войдите, чтобы отправить решение
Лёгкое Ручная проверка Заполните пропуск в коде (2)
+10 XP

В приведённом ниже фрагменте кода из этого урока пропущено одно слово. Определите его и впишите в поле ответа (без кавычек и пробелов).

class Phone
{
    _____ Camera
    {

    }
}
Войдите, чтобы отправить решение
Лёгкое Ручная проверка Заполните пропуск в коде (3)
+10 XP

В приведённом ниже фрагменте кода из этого урока пропущено одно слово. Определите его и впишите в поле ответа (без кавычек и пробелов).

class State
{
    // все равно, что private string _____;
    string defaultVar ="default";
    // поле доступно только из текущего класса
    private string privateVar = "private";
    // доступно из текущего класса и производных классов, которые определены в этом же проекте
    protected private string protectedPrivateVar = "protected private";
    // доступно из текущего класса и производных классов
    protected string protectedVar = "protected";
    // доступно в любом месте текущего проекта
    internal string internalVar = "internal";
    // доступно в любом месте текущего проекта и из классов-наследников в других проектах
    protected internal string protectedInternalVar = "protected internal";
    // доступно в любом месте программы, а также для других программ и сборок
    public string publicVar = "public";

    // по умолчанию имеет модификатор private
    void Print() => Console.WriteLine(defaultVar);

    // метод доступен только из текущего класса
    private void PrintPrivate() => Console.WriteLine(privateVar);

    // доступен из текущего класса и производных классов, которые определены в этом же проекте
    protected private void PrintProtectedPrivate() => Console.WriteLine(protectedPrivateVar);

    // доступен из текущего класса и производных классов
    protected void PrintProtected() => Console.WriteLine(protectedVar);

    // доступен в любом месте текущего проекта
    internal void PrintInternal() => Console.WriteLine(internalVar);

    // доступен в любом месте текущего проекта и из классов-наследников в других проектах
    protected internal void PrintProtectedInternal() => Console.WriteLine(protectedInternalVar);

    // доступен в любом месте программы, а также для других программ и сборок
    public void PrintPublic() => Console.WriteLine(publicVar);
}
Войдите, чтобы отправить решение
Лёгкое Ручная проверка Заполните пропуск в коде (4)
+10 XP

В приведённом ниже фрагменте кода из этого урока пропущено одно слово. Определите его и впишите в поле ответа (без кавычек и пробелов).

class StateConsumer
{
    public void PrintState()
    {
        State _____ = new State();

        // обратиться к переменной defaultVar у нас не получится,
        // так как она имеет модификатор private и класс StateConsumer ее не видит
        Console.WriteLine(state.defaultVar); //Ошибка, получить доступ нельзя

        // то же самое относится и к переменной privateVar
        Console.WriteLine(state.privateVar); // Ошибка, получить доступ нельзя

        // обратиться к переменной protectedPrivateVar не получится,
        // так как класс StateConsumer не является классом-наследником класса State
        Console.WriteLine(state.protectedPrivateVar); // Ошибка, получить доступ нельзя

        // обратиться к переменной protectedVar тоже не получится,
        // так как класс StateConsumer не является классом-наследником класса State
        Console.WriteLine(state.protectedVar); // Ошибка, получить доступ нельзя

        // переменная internalVar с модификатором internal доступна из любого места текущего проекта
        // поэтому можно получить или изменить ее значение
        Console.WriteLine(state.internalVar);

        // переменная protectedInternalVar так же доступна из любого места текущего проекта
        Console.WriteLine(state.protectedInternalVar);

        // переменная publicVar общедоступна
        Console.WriteLine(state.publicVar);
    }
}
Войдите, чтобы отправить решение
Лёгкое Ручная проверка Заполните пропуск в коде (5)
+10 XP

В приведённом ниже фрагменте кода из этого урока пропущено одно слово. Определите его и впишите в поле ответа (без кавычек и пробелов).

class StateConsumer
{
    public void PrintState()
    {
        State state = _____ State();

        state.Print(); //Ошибка, получить доступ нельзя

        state.PrintPrivate(); // Ошибка, получить доступ нельзя

        state.PrintProtectedPrivate(); // Ошибка, получить доступ нельзя

        state.PrintProtected(); // Ошибка, получить доступ нельзя

        state.PrintInternal();    // норм

        state.PrintProtectedInternal();  // норм

        state.PrintPublic();      // норм
    }
}
Войдите, чтобы отправить решение
Среднее Ручная проверка Восстановите код по памяти (1)
+20 XP

В этом фрагменте кода урока пропущены два ключевых элемента. Впишите оба пропущенных значения через запятую в порядке появления (например: x, 5).

public class Person
{
	string _____;
	public Person(string _____) 
	{
		this.name = name;
	}
	public void Print() => Console.WriteLine($"Name: {name}");
}
Войдите, чтобы отправить решение
Среднее Ручная проверка Восстановите код по памяти (2)
+20 XP

В этом фрагменте кода урока пропущены два ключевых элемента. Впишите оба пропущенных значения через запятую в порядке появления (например: x, 5).

class _____
{
    _____ Camera
    {

    }
}
Войдите, чтобы отправить решение
Среднее Ручная проверка Расставьте строки кода в правильном порядке
+20 XP

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

class Phone
    }
    {
}
    struct Camera
{
Войдите, чтобы отправить решение
Сложное Ручная проверка Объясните и модифицируйте пример из урока «Модификаторы доступа»
+30 XP

Опишите своими словами, что делает приведённый пример кода из урока «Модификаторы доступа», и предложите одно осмысленное изменение (например, другое входное значение или дополнительное условие). Приведите итоговый код.

public class Person
{
	string name;
	public Person(string name) 
	{
		this.name = name;
	}
	public void Print() => Console.WriteLine($"Name: {name}");
}
Войдите, чтобы отправить решение
Сложное Ручная проверка Найдите потенциальную проблему в коде урока «Модификаторы доступа»
+30 XP

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

class Phone
{
    struct Camera
    {

    }
}
Войдите, чтобы отправить решение
Мини-проект Ручная проверка Мини-проект по теме «Модификаторы доступа»
+50 XP

Соберите небольшую программу, которая последовательно демонстрирует ключевые идеи урока. Программа должна быть рабочей и содержать минимум два самостоятельно написанных фрагмента, а не просто копию примера из урока.

Войдите, чтобы отправить решение
Домашнее задание Ручная проверка Домашнее задание по теме «Модификаторы доступа»
+25 XP

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

Войдите, чтобы отправить решение

Обсуждение (0)

Войдите, чтобы оставить комментарий.