В чем разница между "private" и "protected Internal"?

Я просто хочу знать, какова фактическая разница между private и защищенным внутренним спецификатором доступа. Как я знаю

Видимый для собственных членов класса: закрытый и защищенный внутренний ДА

Видно для объекта других классов: Оба НЕТ

Видимый для объектов других классов вне коллекции пространства имен: Оба НЕТ

Видно для объекта дочерних классов вне коллекции пространства имен: Оба НЕТ

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

Ответы

Ответ 1

  • Элемент protected internal отображается для любого кода в текущей сборке или в производном классе в другой сборке. В технических словах это логическая дизъюнкция protected и internal.
  • Элемент private отображается только для кода в том же классе.

protected internal на самом деле является вторым наиболее разрешительным модификатором доступа после public.


Стоит отметить, что protected, возможно, более разрешительный, чем internal, поскольку он позволяет получить доступ из кода, который у вас нет контроля (например, других сборок). Пока internal разрешает доступ ко всему коду в текущей сборке, этот код является вашим, и вы контролируете его!

Чтобы перефразировать, члены protectedprotected internal) являются частью общедоступного API вашей сборки (и поэтому должны быть документированы). internal членов нет.

Ответ 2

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

Visibility

Ответ 3

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

Ответ 4

закрытый

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

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

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

Ответ 5

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

LE: прочитайте комментарий Маттиаса Буэленса для этого.

Ответ 6

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

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

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

Ответ 7

Я пытался понять различия между защищенным внутренним и внутренним в контексте .NET, прочитав описание, предоставленное на разных форумах и блогах. Я действительно не понял, тогда я создал созданную отдельную сборку с использованием VS2015. Вероятно, теперь у меня есть основное понимание. Я хотел бы поделиться с вами, это может быть полезно кому-то. Я попытался использовать поля, объявленные в одной сборке из другой сборки. Также я попытался получить из класса, который был объявлен в другой сборке. Вот код для class1.cs из сборки 1

namespace Z_Dll_1
{
    public class PublicBaseClassAssemblyOne
    {
        internal int _myinternal = 200;
        protected internal int _protectedinternal = 100;
        protected int _myProtected = 123;
        private int _myPrivate = 2;
        public int _myPublic = 45;
    }

    public class DerivedClassAssemblyOne : PublicBaseClassAssemblyOne
    {
        protected internal int intM = 10;
    }

    internal class MyInternalClass
    {
        public void MyMethod()
        {
            Console.WriteLine("Method one with internal class");
            PublicBaseClassAssemblyOne cl1 = new PublicBaseClassAssemblyOne();
            cl1._myinternal = 1000; //Internal type is available since it is in same assembly
            cl1._protectedinternal = 10; // protected internal is available
            cl1._myPublic = 2;  // Public OK
            //cl1.myPrivate = ?? // nor available since it is private

            DerivedClassAssemblyOne drOne = new DerivedClassAssemblyOne();
            drOne._myinternal = 30; // Internal and available from derived class
            drOne._myPublic = 1; // Public 
            drOne._protectedinternal = 2; // Able to be accessed from same assembly or derived class from other assembly
        }
    }
}

Вот код из другой сборки, class2.cs   используя Z_Dll_1;

namespace Z_Dll_2
{
    public class ClassAssembly2
    {
        public ClassAssembly2()
        {
            PublicBaseClassAssemblyOne classfromOtherAssembly = new PublicBaseClassAssemblyOne();
            classfromOtherAssembly._myPublic = 0; //Only public is available
        }
    }

    public class ClassDerivedFromOtherAssemblyClass : PublicBaseClassAssemblyOne
    {
        public ClassDerivedFromOtherAssemblyClass()
        {
        }
        void ClassDerivedFromOtherAssemblyClassTestMethod()
        {
            //_myinternal = 200; // can't access since it was internal to other assembly
            _protectedinternal = 100; // this can be accessed as it is  derived class from other class that has protected internal 
            _myProtected = 123; // Ordinary protected data accessed from derived class
            //_myPrivate = 2; //Private member can't be accessed from  derived class
            _myPublic = 45; // Public can be accessed anyway

            //Try to create an instance of internal class
            //MyInternalClass intClass = new MyInternalClass(); //Not accessible from this assembly
        }
    }
}