¿Cuál es la diferencia entre público, privado, protegido y sin modificador de acceso?


Todos mis años de universidad he estado usando public, y quisiera saber la diferencia entre public, private, y protected?

También ¿qué hace static en lugar de no tener nada?

Author: Liam, 2009-03-05

14 answers

Modificadores de acceso

Público

El tipo o miembro puede ser accedido por cualquier otro código en el mismo ensamblado u otro ensamblado que lo haga referencia.

Privado

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

Protegido

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

Private protected (añadido en C# 7.2)

El tipo o miembro solo se puede acceder por código en la misma clase o estructura, o en una clase derivada del mismo ensamblado, pero no de otro ensamblado.

Interno

El tipo o miembro puede ser accedido por cualquier código en el mismo ensamblado, pero no desde otro ensamblado.

Interno Protegido

El tipo o miembro puede ser accedido por cualquier código en el mismo ensamblado, o por cualquier clase derivada en otro ensamblado.

Cuando no se establece un modificador de acceso, se utiliza un modificador de acceso predeterminado. Así que siempre hay alguna forma de modificador de acceso incluso si no está establecido.

Static

El modificador estático en una clase significa que la clase no puede ser instanciada, y que todos sus miembros son estáticos. Un miembro estático tiene una versión independientemente de cuántas instancias de su tipo envolvente se crean.

Una clase estática es básicamente lo mismo que una clase no estática, pero hay una diferencia: una clase estática no puede ser instanciada externamente. En otras palabras, no puede usar la palabra clave new para crear una variable del tipo class. Dado que no hay ninguna variable de instancia, puede acceder a los miembros de una clase estática utilizando el propio nombre de clase.

Sin embargo, hay una cosa tal como un estático constructor . Cualquier clase puede tener uno de estos, incluyendo clases estáticas. No se pueden llamar directamente y no pueden tener parámetros (que no sean parámetros de tipo en la propia 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 así:

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

    public static string Bar { get; set; }
}

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

MyStaticClass.ServiceMethod(...);
 895
Author: mbillard,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-09-04 08:36:38

Public - Si puedes ver la clase, entonces puedes ver el método

Private - Si eres parte de la clase, entonces puedes ver el método, de lo contrario no.

Protected - Igual que Private, más todos los descendientes también pueden ver el método.

Static (class) - ¿Recuerda la distinción entre" Class "y" Object"? Olvida todo eso. Son lo mismo con "estática"... la clase es la única instancia de sí mismo.

Static (method) - Cada vez que use este método, tendrá un marco de referencia independiente de la instancia real de la clase de la que forma parte.

 144
Author: JosephStyons,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-03-05 17:22:22

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

Visibilidad

Para los valores predeterminados si no pone ningún modificador de acceso delante, vea aquí:
¿Visibilidad predeterminada para las clases y miembros de C# (campos, métodos, etc.)?

No anidado

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
 131
Author: Stefan Steiger,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 10:31:39

Respecto a la cuestión de Nada

  • Los tipos de espacio de nombres son internos por defecto
  • Cualquier miembro de tipo, incluidos los tipos anidados, es privado por defecto
 22
Author: leppie,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-03-05 17:27:55

introduzca la descripción de la imagen aquí

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();
        }
    }
}
 17
Author: Narottam Goyal,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-05-24 07:24:49

Hmm.

Vea aquí: Modificadores de acceso.

En pocas palabras:

Public da al método o tipo visibilidad completa de otros tipos/clases.

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

Protected es similar a private excepto que las clases derivadas también pueden acceder a protected método.

"Nada" es VB.NET es equivalente a null. Aunque si se refiere a "nada" que significa "no modificador de acceso", entonces depende, aunque una regla general muy aproximada (ciertamente en C#) es que si no especifica explícitamente un modificador de acceso, la declaración de método/variable suele ser restricted 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 acceso modificador especificado explícitamente.

 11
Author: CraigTP,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-01-24 22:41:39

Public - puede ser accedido por cualquier persona en cualquier lugar.
private - solo se puede acceder desde con en la clase de la que forma parte.
protected - solo se puede acceder desde con en la clase o cualquier objeto que hereda fuera de la clase.

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

 8
Author: Tony,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-09-17 13:20:46

Reposting the awesome diagrams from this answer.

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

private:
introduzca la descripción de la imagen aquí

private protected: - añadido en C# 7.2
introduzca la descripción de la imagen aquí

internal:
introduzca la descripción de la imagen aquí

protected:
introduzca la descripción de la imagen aquí

protected internal:
introduzca la descripción de la imagen aquí

public:
introduzca la descripción de la imagen aquí

 7
Author: Paul,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-07-03 08:25:40

Mmm...

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

Se puede acceder directamente desde la definición de la clase.

 4
Author: gbianchi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-03-05 13:53:14

Un estado de Private indica que las variables solo pueden ser accedidas 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 anterior podemos ver la deferencia entre privado y protegido... estoy creo que ambos son iguales.... así que lo que la necesidad de que dos comandos separados"

Compruebe MSDN enlace para más información

 4
Author: Grant Hood,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-01-07 17:57:32

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.

 3
Author: jpfollenius,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-03-05 13:52:47

Tenga cuidado con la accesibilidad de sus clases. Las clases y métodos públicos y protegidos son accesibles por defecto para todos.

Además, Microsoft no es muy explícito al mostrar los modificadores de acceso (público, protegido, etc.. palabras clave) cuando se crean nuevas clases en Visual Studio. Por lo tanto, tenga mucho cuidado y piense en la accesibilidad de su clase porque es la puerta a sus internos de implementación.

 3
Author: Patrick Peters,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-03-05 14:21:00

Creo que está relacionado con un buen diseño de OOP. Si usted es un desarrollador de una biblioteca que desea ocultar el funcionamiento interno de su biblioteca. De esa 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 protegerse.

 2
Author: Darius Kucinskas,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-08-28 19:53:25

C # tiene en total 6 modificadores de acceso:

Private: 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 ensamblado o tipos fuera del ensamblado contenedor. es decir, el acceso está limitado al tipo que contiene solamente.

Protegido: El miembro declarado con esta accesibilidad puede ser visible dentro de los tipos derivados del tipo que contiene dentro del conjunto que contiene, y los tipos derivados del tipo que contiene fuera del conjunto que contiene. es decir, el acceso está limitado a los tipos derivados del tipo que contiene.

Interno: El miembro declarado con esta accesibilidad puede ser visible dentro de la asamblea que contiene este miembro, no es visible para ninguna asamblea fuera de la asamblea que contiene. es decir, el acceso está limitado a contener solo el ensamblado.

Interno protegido: El miembro declarado con este la accesibilidad puede ser visible dentro de los tipos derivados del tipo que contiene dentro o fuera del ensamblaje que contiene, también es visible para cualquier tipo dentro del ensamblaje que contiene. es decir, el acceso se limita a contener tipos ensamblados o derivados.

Public: El miembro declarado con esta accesibilidad puede ser visible dentro de la asamblea que contiene a este miembro, o cualquier otra asamblea que haga referencia a la asamblea que contiene. es decir, el acceso no está limitado.

C # 7.2 es añadir un nuevo nivel de accesibilidad:

Private protected: El miembro declarado con esta accesibilidad puede ser visible dentro de los tipos derivados de este tipo contenedor dentro del ensamblado contenedor. No es visible para ningún tipo no derivado del tipo que contiene, o fuera del conjunto que contiene. es decir, el acceso está limitado a tipos derivados dentro del ensamblado que contiene.

Fuente incluyendo un código de ejemplo del nuevo acceso protegido privado modificador

 1
Author: Baccata,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-12-20 09:27:01