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

567

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

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

Теги:
access-modifiers

12 ответов

777
Лучший ответ

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

публичный

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

частный

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

защищенный

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

внутренний

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

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

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

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

Static

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

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

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

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

    public static string Bar { get; set; }
}

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

MyStaticClass.ServiceMethod(...);
  • 14
    И у вас могут быть статические методы в нестатических классах, верно?
  • 13
    Да, они будут вести себя так же, как в моем примере.
Показать ещё 8 комментариев
126

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

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

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

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

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

  • 1
    Разве вы не можете использовать статические методы в нестатическом классе?
  • 1
    Да, но я говорил о статическом классе. Я добавил отдельную запись для описания статических методов. Спасибо за улов.
Показать ещё 4 комментария
121

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

Изображение 1030

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

невложенных

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
  • 0
    Внутренний производный класс может быть принят RT? Это неправильно ...
  • 1
    @ ᴀʀᴜn BᴇrtiL: Ты уверен? Производный класс в другой сборке?
Показать ещё 3 комментария
19

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

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

Изображение 1031

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();
        }
    }
}
  • 1
    Я не вижу, что этот ответ добавляет ко многим другим ответам за последние пять лет.
  • 2
    Это просто простое объяснение. Поскольку другие ответы немного запутаны и наполовину ответили :)
Показать ещё 2 комментария
10

Хм.

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

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

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

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

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

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

public class MyClass
{
    string s = "";
}

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

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

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

8

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

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

4

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

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

Подробнее о MSDN

4

ммм...

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

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

3

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

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

3

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

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

2

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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню