В C# в чем разница между публичным, приватным, защищенным и не имеющим модификатора доступа?

Все мои студенческие годы я использую publicи хотел бы знать разницу между public, private, а также protected?

И что делает static делать, а не иметь ничего?

20 ответов

Решение

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

общественности

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

частный

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

защищенный

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

частная защита (добавлено в C# 7.2)

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

внутренний

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

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

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

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

статический

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

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

Однако есть такая вещь, как статический конструктор. Любой класс может иметь один из них, включая статические классы. Они не могут быть вызваны напрямую и не могут иметь параметров (кроме параметров любого типа в самом классе). Статический конструктор вызывается автоматически для инициализации класса перед созданием первого экземпляра или ссылками на любые статические члены. Выглядит так:

static class Foo()
{
    static Foo()
    {
        Bar = "fubar";
    }

    public static string Bar { get; set; }
}

Статические классы часто используются как сервисы, вы можете использовать их так:

MyStaticClass.ServiceMethod(...);

Графический обзор (в двух словах)

видимость

По умолчанию, если вы не указали модификатор доступа, смотрите здесь:
Видимость по умолчанию для классов и членов C# (поля, методы и т. Д.)?

Невложенных

enum                              public
non-nested classes / structs      internal
interfaces                        internal
delegates in namespace            internal
class/struct member(s)            private
delegates nested in class/struct  private

Вложенные:

nested enum      public
nested interface public
nested class     private
nested struct    private

Public - если вы видите класс, вы можете увидеть метод

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

Защищено - То же, что и Private, плюс все потомки также могут видеть метод.

Статический (класс) - Помните различие между "Классом" и "Объектом"? Забудь обо всем этом. Они одинаковы со "статическим"... класс является единственным экземпляром самого себя.

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

Репостить удивительные диаграммы из этого ответа.

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

private:

private protected: - добавлено в C# 7.2

internal:

protected:

protected internal:

public:

Еще один визуальный подход текущего модификатора доступа (C# 7.2). Надеемся, что схема помогает запомнить это проще.

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

Снаружи внутри

Если вам трудно вспомнить модификаторы доступа с двумя адресами, запомните это снаружи.

  • частная защита: частная снаружи (та же сборка) защищенная внутри (та же сборка)
  • внутренняя защита: внутренняя защита (такая же сборка) внутренняя защита (такая же сборка)

using System;

namespace ClassLibrary1
{
    public class SameAssemblyBaseClass
    {
        public string publicVariable = "public";
        protected string protectedVariable = "protected";
        protected internal string protected_InternalVariable = "protected internal";
        internal string internalVariable = "internal";
        private string privateVariable = "private";
        public void test()
        {
            // OK
            Console.WriteLine(privateVariable);

            // OK
            Console.WriteLine(publicVariable);

            // OK
            Console.WriteLine(protectedVariable);

            // OK
            Console.WriteLine(internalVariable);

            // OK
            Console.WriteLine(protected_InternalVariable);
        }
    }

    public class SameAssemblyDerivedClass : SameAssemblyBaseClass
    {
        public void test()
        {
            SameAssemblyDerivedClass p = new SameAssemblyDerivedClass();

            // NOT OK
            // Console.WriteLine(privateVariable);

            // OK
            Console.WriteLine(p.publicVariable);

            // OK
            Console.WriteLine(p.protectedVariable);

            // OK
            Console.WriteLine(p.internalVariable);

            // OK
            Console.WriteLine(p.protected_InternalVariable);
        }
    }

    public class SameAssemblyDifferentClass
    {
        public SameAssemblyDifferentClass()
        {
            SameAssemblyBaseClass p = new SameAssemblyBaseClass();

            // OK
            Console.WriteLine(p.publicVariable);

            // OK
            Console.WriteLine(p.internalVariable);

            // NOT OK
            // Console.WriteLine(privateVariable);

            // Error : 'ClassLibrary1.SameAssemblyBaseClass.protectedVariable' is inaccessible due to its protection level
            //Console.WriteLine(p.protectedVariable);

            // OK
            Console.WriteLine(p.protected_InternalVariable);
        }
    }
}

 using System;
        using ClassLibrary1;
        namespace ConsoleApplication4

{
    class DifferentAssemblyClass
    {
        public DifferentAssemblyClass()
        {
            SameAssemblyBaseClass p = new SameAssemblyBaseClass();

            // NOT OK
            // Console.WriteLine(p.privateVariable);

            // NOT OK
            // Console.WriteLine(p.internalVariable);

            // OK
            Console.WriteLine(p.publicVariable);

            // Error : 'ClassLibrary1.SameAssemblyBaseClass.protectedVariable' is inaccessible due to its protection level
            // Console.WriteLine(p.protectedVariable);

            // Error : 'ClassLibrary1.SameAssemblyBaseClass.protected_InternalVariable' is inaccessible due to its protection level
            // Console.WriteLine(p.protected_InternalVariable);
        }
    }

    class DifferentAssemblyDerivedClass : SameAssemblyBaseClass
    {
        static void Main(string[] args)
        {
            DifferentAssemblyDerivedClass p = new DifferentAssemblyDerivedClass();

            // NOT OK
            // Console.WriteLine(p.privateVariable);

            // NOT OK
            //Console.WriteLine(p.internalVariable);

            // OK
            Console.WriteLine(p.publicVariable);

            // OK
            Console.WriteLine(p.protectedVariable);

            // OK
            Console.WriteLine(p.protected_InternalVariable);

            SameAssemblyDerivedClass dd = new SameAssemblyDerivedClass();
            dd.test();
        }
    }
}

По вопросу Ничего

  • Типы пространств имен по умолчанию являются внутренними
  • Любой член типа, включая вложенные типы, по умолчанию являются закрытыми

Хм.

Смотрите здесь: Access Modifiers.

В двух словах:

Public дает методу или типу полную видимость из других типов / классов.

Private разрешает только типу, содержащему приватный метод / переменную, доступ к приватному методу / переменной (обратите внимание, что вложенные классы также имеют доступ к содержащим классам приватных методов / переменных).

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

"Ничто" - это эквивалент VB.NET нулю. Хотя если вы имеете в виду "ничего", означающее "нет модификатора доступа", то это зависит, хотя очень грубое практическое правило (безусловно, в C#) заключается в том, что если вы не укажете явно модификатор доступа, метод / переменная объявление обычно настолько ограничено, насколько это возможно. т.е.

public class MyClass
{
    string s = "";
}

эффективно так же, как:

public class MyClass
{
    private string s = "";
}

Связанная статья MSDN предложит полное описание, когда явно не указан модификатор доступа.

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

Ничто не похоже на ноль, но в VB.
Статический означает, что у вас есть один экземпляр этого объекта, метод для каждого экземпляра этого класса.

Ммм...

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

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

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

"Из приведенной выше таблицы мы можем видеть разницу между частным и защищенным... я думаю, что оба они одинаковы… так в чем же необходимость этих двух отдельных команд"

Проверьте ссылку MSDN для получения дополнительной информации

  • означает, что к нему может получить доступ любой класс в любой сборке, включая сам класс.
  • означает, что к нему может получить доступ сам класс (в определении класса), и к нему может получить доступ любой класс в текущей сборке, но вне сборки к нему может получить доступ только класс, наследующий класс, или сам класс (если это частичный класс) - в основном это означает внутри сборки и вне сборки.
  • означает, что к нему может получить доступ только сам класс или класс, который его наследует, и этот класс может быть в любой сборке
  • означает, что к нему может получить доступ сам класс или любой класс в сборке, но нельзя получить доступ вообще за пределами сборки, если только сам класс (т.е. это частичный класс)
  • означает, что к нему может получить доступ только сам класс, или к нему может получить доступ класс, который его наследует, и только если этот класс находится в текущей сборке. Вне сборки доступ к нему может получить только сам класс (т. Е. Это частичный класс) - в основном объединяет и, или другой способ поместить его - вне сборки и внутри сборки.
  • означает, что к нему может получить доступ только сам класс
  • без модификатора доступа: доступ по умолчанию для всего в C # - это «самый ограниченный доступ, который вы могли объявить для этого члена»., который предназначен для члена / метода / вложенного класса в классе и для невложенного класса.

В приведенном выше тексте «доступ» означает доступ через объект типа класса, который внутри метода самого класса будет неявным. объект, или, возможно, метод создает экземпляр явного объекта текущего типа класса и обращается к нему через этот объект. Оба считаются доступными для самого класса, и поэтому правила доступа одинаковы. Это также относится к доступу, выполняемому из статического метода, или когда осуществляется доступ к статическому члену / методу, за исключением того, что доступ выполняется с использованием области класса, а не объекта и. Член / метод статического класса должен быть явно сделан или он не будет компилироваться.

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

Вы можете иметь публичный член / метод / вложенный класс в или вложенный класс - только спецификатор доступа (в полном имени выполняемого доступа), который ниже уровня, необходимого для текущего доступа, предотвращает доступ.

Наследование в C # всегда в отличие от C++, который может наследовать частным или защищенным образом, который затем изменяет доступ всех классов, которые затем наследуются от класса, наследуемого от этого класса, а также доступ через объект / через область видимости класса типа класса, который наследует частным образом / protectedly от класса и класса, который наследуется от класса, который наследует частным / защищенным образом от класса, и так далее. Доступ изменен таким образом, что все модификаторы доступа менее ограничительны, чем или сделаны а также соответственно.

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

Кроме того, Microsoft не очень хорошо показывает модификаторы доступа (общедоступные, защищенные и т. Д. Ключевые слова) при создании новых классов в Visual Studio. Так что будьте осторожны и подумайте о своей доступности для своего класса, потому что это дверь для ваших внутренних возможностей реализации.

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

Статические члены - один на класс, а не один на экземпляр.

Я думаю, что это связано с хорошим дизайном ООП. Если вы разработчик библиотеки, вы хотите скрыть внутреннюю работу вашей библиотеки. Таким образом, вы сможете позже изменить внутреннюю работу вашей библиотеки. Таким образом, вы называете свои члены и вспомогательные методы закрытыми, и только методы интерфейса являются открытыми. Методы, которые должны быть перезаписаны, должны быть защищены.

C# имеет всего 6 модификаторов доступа:

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

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

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

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

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

C# 7.2 добавляет новый уровень доступности:

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

Исходный код, включающий пример кода нового модификатора частного защищенного доступа

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

private К типу или члену можно получить доступ только из кода в том же классе или структуре.

internal Внутренние типы или члены доступны только в файлах в той же сборке.

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

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

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

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

В C# 11 вы также можете использовать модификатор доступа к файлу .

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

      // In File1.cs:
file interface IWidget
{
    int ProvideAnswer();
}

file class HiddenWidget
{
    public int Work() => 42;
}

public class Widget : IWidget
{
    public int ProvideAnswer()
    {
        var worker = new HiddenWidget();
        return worker.Work();
    }
}

Описание всех модификаторов доступа для C#

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

https://github.com/TropinAlexey/C-sharp-Access-Modifiers

Учитывая, что все сайты Stack Exchange, включая Stack Overflow, теперь поддерживают таблицы уценки, мне не хватало одной из ответов здесь.

Таблица результатов:

Источник:

https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/access-modifiers#summary-table

https://meta.stackexchange.com/questions/356997/new-feature-table-support

Другие вопросы по тегам