В чем разница между "private" и "protected Internal"?
Я просто хочу знать, какова фактическая разница между private и защищенным внутренним спецификатором доступа. Как я знаю
Видимый для собственных членов класса: закрытый и защищенный внутренний ДА
Видно для объекта других классов: Оба НЕТ
Видимый для объектов других классов вне коллекции пространства имен: Оба НЕТ
Видно для объекта дочерних классов вне коллекции пространства имен: Оба НЕТ
Если private делает то же самое, что защищенный внутренний, то почему нам нужны оба только одного, должно быть достаточно или нет?
Ответы
Ответ 1
- Элемент
protected internal
отображается для любого кода в текущей сборке или в производном классе в другой сборке. В технических словах это логическая дизъюнкция protected
и internal
.
- Элемент
private
отображается только для кода в том же классе.
protected internal
на самом деле является вторым наиболее разрешительным модификатором доступа после public
.
Стоит отметить, что protected
, возможно, более разрешительный, чем internal
, поскольку он позволяет получить доступ из кода, который у вас нет контроля (например, других сборок). Пока internal
разрешает доступ ко всему коду в текущей сборке, этот код является вашим, и вы контролируете его!
Чтобы перефразировать, члены protected
(и protected 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
}
}
}