¿Cuál es la diferencia entre público, privado, protegido y que no tiene ningún modificador de acceso?

Todos mis años universitarios que he estado usando public , y me gustaría saber la diferencia entre public , private y protected ?

Además, ¿qué hace static en comparación con no tener nada?

Modificadores de acceso

público

Se puede acceder al tipo o miembro mediante cualquier otro código en el mismo conjunto u otro conjunto que lo haga referencia.

privado

El tipo o miembro solo se puede acceder por código en la misma clase o estructura.

protegido

Solo se puede acceder al tipo o miembro mediante código en la misma clase o estructura, o en una clase derivada.

privado protegido (agregado en C # 7.2)

Solo se puede acceder al tipo o miembro mediante código en la misma clase o estructura, o en una clase derivada del mismo ensamblado, pero no desde otro ensamblado.

interno

Se puede acceder al tipo o miembro mediante cualquier código en el mismo ensamblaje, pero no desde otro ensamblado.

protegido interno

Se puede acceder al tipo o miembro mediante cualquier código en el mismo conjunto o por cualquier clase derivada en otro ensamblado.

Cuando no se establece ningún modificador de acceso, se utiliza un modificador de acceso predeterminado. Por lo tanto, siempre hay algún tipo de modificador de acceso, incluso si no está configurado.

Estático

El modificador estático de una clase significa que no se puede crear una instancia de la clase y que todos sus miembros son estáticos. Un miembro estático tiene una versión independientemente de cuántas instancias de su tipo adjunto se creen.

Una clase estática es básicamente la misma que una clase no estática, pero hay una diferencia: una clase estática no se puede instanciar externamente. En otras palabras, no puede usar la nueva palabra clave para crear una variable del tipo de clase. Como no hay una variable de instancia, puede acceder a los miembros de una clase estática utilizando el nombre de la clase en sí.

Sin embargo, existe algo así como un constructor estático . Cualquier clase puede tener uno de estos, incluidas las clases estáticas. No se pueden llamar directamente y no pueden tener parámetros (que no sean parámetros de tipo en la clase). Se llama automáticamente a un constructor estático para inicializar la clase antes de que se cree la primera instancia o se haga referencia a cualquier miembro estático. Se ve como esto:

 static class Foo() { static Foo() { Bar = "fubar"; } public static string Bar { get; set; } } 

Las clases estáticas a menudo se usan como servicios, puede usarlas de la siguiente manera:

 MyStaticClass.ServiceMethod(...); 

Público : si puedes ver la clase, entonces puedes ver el método

Privado : si formas parte de la clase, puedes ver el método; de lo contrario, no.

Protegido : lo mismo que Privado, y todos los descendientes también pueden ver el método.

Estático (clase) : ¿recuerda la distinción entre “Clase” y “Objeto”? Olvida todo eso. Son lo mismo con “estático” … la clase es la única instancia de sí mismo.

Estático (método) : siempre que utilice este método, tendrá un marco de referencia independiente de la instancia real de la clase de la que forma parte.

Una descripción gráfica (resumen en pocas palabras)

Visibilidad

Para los valores predeterminados si no pones ningún modificador de acceso en el frente, mira aquí:
Visibilidad predeterminada para clases C # y miembros (campos, métodos, etc.)

No nested

 enum public non-nested classes / structs internal interfaces internal delegates in namespace internal class/struct member(s) private delegates nested in class/struct private 

Anidado:

 nested enum public nested interface public nested class private nested struct private 

En cuanto a la cuestión de nada

  • Los tipos de espacio de nombres son internos por defecto
  • Cualquier miembro de tipo, incluidos los tipos nesteds, son privados de forma predeterminada

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

Hmm.

Ver aquí: Modificadores de acceso .

En una palabra:

Public da el método o escribe visibilidad completa desde otros tipos / clases.

Privado solo permite el tipo que contiene el método privado / acceso variable al método / variable privado (tenga en cuenta que las clases anidadas también tienen acceso a las clases privadas que contienen las variables / métodos).

Protected es similar a private, excepto que las clases derivadas también pueden acceder a métodos protegidos.

“Nothing” es el equivalente de VB.NET a null. Aunque si te refieres a “nada” que significa “sin modificador de acceso”, entonces depende, aunque una regla empírica (por cierto en C #) es que si no especificas explícitamente un modificador de acceso, el método / variable statement es usualmente tan restringida como puede ser. es decir

 public class MyClass { string s = ""; } 

es efectivamente lo mismo que:

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

El artículo enlazado de MSDN ofrecerá una descripción completa cuando no haya un modificador de acceso explícitamente especificado.

público : cualquier persona puede acceder a él desde cualquier lugar.
privado : solo se puede acceder desde dentro de la clase de la que forma parte.
protected : solo se puede acceder desde dentro de la clase o desde cualquier objeto que herede de la clase.

Nada es como nulo, pero en VB.
Estático significa que tiene una instancia de ese objeto, método para cada instancia de esa clase.

Reposicionando los impresionantes diagtwigs de esta respuesta .

Aquí están todos los modificadores de acceso en los diagtwigs de Venn, desde más limitadores a más promiscuos:

private :
enter image description here

private protected : – agregado en 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

mmm …

Estático significa que puede acceder a esa función sin tener una instancia de la clase.

Puede acceder directamente desde la definición de la clase.

Un estado de Privado indica que solo se puede acceder a las variables por objetos de la misma clase. El estado protegido extiende ese acceso para incluir también a los descendientes de la clase.

“de la tabla de arriba podemos ver la deferencia entre privado y protegido … creo que ambos son los mismos … así que ¿cuál es la necesidad de esos dos comandos separados?

Verifique el enlace de MSDN para más información

Esos modificadores de acceso especifican dónde están visibles sus miembros. Probablemente deberías leer esto. Tome el enlace dado por IainMH como punto de partida.

Los miembros estáticos son uno por clase y no uno por instancia.

Cuidado con su accesibilidad de sus clases. Las clases y métodos públicos y protegidos están disponibles de forma predeterminada para todos.

Además, Microsoft no es muy explícito al mostrar los modificadores de acceso (palabras clave públicas, protegidas, etc.) cuando se crean nuevas clases en Visual Studio. Por lo tanto, cuídate bien y piensa en tu accesibilidad de tu clase porque es la puerta a tu implementación interna.

Creo que está relacionado con un buen diseño de POO. Si usted es desarrollador de una biblioteca, quiere ocultar el funcionamiento interno de su biblioteca. De esta manera, puede modificar el funcionamiento interno de su biblioteca más adelante. Así que pones tus miembros y métodos de ayuda como privados, y solo los métodos de interfaz son públicos. Los métodos que deben sobrescribirse deben estar protegidos.

C # tiene un total de 6 modificadores de acceso:

privado : el miembro declarado con esta accesibilidad puede ser visible dentro del tipo contenedor, no es visible para ningún tipo derivado, otros tipos en el mismo conjunto o tipos fuera del conjunto contenedor. es decir, el acceso está limitado solo al tipo contenedor.

protected : el miembro declarado con esta accesibilidad puede ser visible dentro de los tipos derivados del tipo contenedor dentro del ensamblaje contenedor, y los tipos derivados del tipo contenedor fuera del ensamblaje contenedor. es decir, el acceso está limitado a tipos derivados del tipo contenedor.

interno : el miembro declarado con esta accesibilidad puede ser visible dentro del ensamblaje que contiene este miembro, no es visible para ningún ensamblaje fuera del ensamblaje que lo contiene. es decir, el acceso está limitado a contener ensamblaje solamente.

interno protegido : el miembro declarado con esta accesibilidad puede ser visible dentro de los tipos derivados del tipo contenedor dentro o fuera del conjunto contenedor, también es visible para cualquier tipo dentro del conjunto contenedor. es decir, el acceso está limitado a contener ensamblaje o tipos derivados.

público : el miembro declarado con esta accesibilidad puede ser visible dentro del ensamblaje que contiene este miembro, o cualquier otro ensamblaje que haga referencia al ensamblaje que lo contiene. es decir, el acceso no está limitado.

C # 7.2 está agregando un nuevo nivel de accesibilidad:

privado protegido : el miembro declarado con esta accesibilidad puede ser visible dentro de los tipos derivados de este tipo que contiene dentro del conjunto contenedor. No es visible para ningún tipo que no se derive del tipo contenedor o fuera del ensamblaje contenedor. es decir, el acceso está limitado a tipos derivados dentro del conjunto contenedor.

Fuente que incluye un código de muestra del nuevo modificador de acceso privado protegido