В чем разница между public, private, protected и отсутствием модификатора доступа?

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

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

14 ответов


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

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

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

частная

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

защищенный

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

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

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

внутренние

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

защищенная внутренняя

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

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

Static

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

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

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

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

    public static string Bar { get; set; }
}

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

MyStaticClass.ServiceMethod(...);

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

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

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

Static (class)

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


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

Visibility

для значений по умолчанию, если вы не ставите модификатор доступа спереди, см. здесь:
видимость по умолчанию для классов и членов 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

по вопросу ничего

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

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

Мда.

смотрите здесь: Модификаторы Доступа.

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

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

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

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

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

public class MyClass
{
    string s = "";
}

практически аналогично:

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

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


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

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


перепечатка удивительных диаграмм из ответ.

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

private:
enter image description here

private protected: - добавлено в C# 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


МММ...

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

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


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

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

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


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

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


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

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


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


в C# в общей сумме 6 модификаторы доступа:

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

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

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

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

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

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

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

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