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

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

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

Ответы [ 15 ]

956 голосов
/ 05 марта 2009

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

С docs.microsoft.com

* 1009 публика *

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

частный

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

защищен

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

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

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

внутренний

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

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

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

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

Статический

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

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

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

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

    public static string Bar { get; set; }
}

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

MyStaticClass.ServiceMethod(...);
155 голосов
/ 05 марта 2009

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

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

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

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

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

146 голосов
/ 11 апреля 2014

Графический обзор (краткое содержание)

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
22 голосов
/ 05 марта 2009

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

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

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();
        }
    }
}
15 голосов
/ 01 апреля 2018

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

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

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

11 голосов
/ 05 марта 2009

Хм.

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

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

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

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

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

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

public class MyClass
{
    string s = "";
}

фактически совпадает с:

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

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

8 голосов
/ 05 марта 2009

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

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

5 голосов
/ 21 февраля 2019

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

interactive access modifiers svg

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

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

  • частная защита : частная снаружи (та же сборка) защита внутри (та же сборка)
  • защищенный внутренний : защищенный внешний (та же сборка) внутренний внутри (та же сборка)
4 голосов
/ 07 июля 2010

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

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

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

...