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

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

И что делает static в отличие от ничего?

Ответ 1

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

От docs.microsoft.com

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

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

частный

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

защищенный

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

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

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

внутренний

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

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

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

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

статический

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

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

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

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

    public static string Bar { get; set; }
}

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

MyStaticClass.ServiceMethod(...);

Ответ 2

Публичная. Если вы можете увидеть класс, вы можете увидеть метод

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

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

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

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

Ответ 3

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

Visibility

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

невложенных

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

Ответ 4

Относительно вопроса Ничего

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

Ответ 5

enter image description here

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();
        }
    }
}

Ответ 6

Репостить потрясающие диаграммы из этого ответа.

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

private:
enter image description here

private protected: - добавлено в С# 7.2
enter image description here

internal:
enter image description here

protected:
enter image description here

protected internal:
enter image description here

public:
enter image description here

Ответ 7

Хм.

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

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

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

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

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

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

public class MyClass
{
    string s = "";
}

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

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

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

Ответ 8

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

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

Ответ 9

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

interactive access modifiers svg

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

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

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

Ответ 10

ммм...

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

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

Ответ 11

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

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

Подробнее о MSDN

Ответ 12

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

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

Ответ 13

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

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

Ответ 14

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

Ответ 15

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

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

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

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

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

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

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

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

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