¿Cuáles son los modificadores de acceso predeterminados en C #?

384

¿Cuál es el modificador de acceso predeterminado para clases, métodos, miembros, constructores, delegados e interfaces?

Surya sasidhar
fuente

Respuestas:

486

El acceso predeterminado para todo en C # es "el acceso más restringido que podría declarar para ese miembro" .

Así por ejemplo:

namespace MyCompany
{
    class Outer
    {
        void Foo() {}
        class Inner {}
    }
}

es equivalente a

namespace MyCompany
{
    internal class Outer
    {
        private void Foo() {}
        private class Inner {}
    }
}

El único tipo de excepción a esto es hacer que una parte de una propiedad (generalmente el establecedor) sea más restringida que la accesibilidad declarada de la propiedad en sí:

public string Name
{
    get { ... }
    private set { ... } // This isn't the default, have to do it explicitly
}

Esto es lo que dice la especificación C # 3.0 (sección 3.5.1):

Dependiendo del contexto en el que se lleva a cabo una declaración de miembro, solo se permiten ciertos tipos de accesibilidad declarada. Además, cuando una declaración de miembro no incluye ningún modificador de acceso, el contexto en el que tiene lugar la declaración determina la accesibilidad declarada predeterminada.

  • Los espacios de nombres implícitamente tienen accesibilidad pública declarada. No se permiten modificadores de acceso en las declaraciones de espacio de nombres.
  • Los tipos declarados en unidades de compilación o espacios de nombres pueden tener accesibilidad declarada pública o interna y, por defecto, accesibilidad declarada interna.
  • Los miembros de la clase pueden tener cualquiera de los cinco tipos de accesibilidad declarada y, por defecto, accesibilidad privada declarada. (Tenga en cuenta que un tipo declarado como miembro de una clase puede tener cualquiera de los cinco tipos de accesibilidad declarada, mientras que un tipo declarado como miembro de un espacio de nombres solo puede tener accesibilidad declarada pública o interna).
  • Los miembros de estructura pueden tener accesibilidad declarada pública, interna o privada y por defecto accesibilidad declarada privada porque las estructuras están implícitamente selladas. Los miembros de estructura introducidos en una estructura (es decir, no heredada por esa estructura) no pueden tener accesibilidad declarada protegida o protegida interna. (Tenga en cuenta que un tipo declarado como miembro de una estructura puede tener accesibilidad declarada pública, interna o privada, mientras que un tipo declarado como miembro de un espacio de nombres solo puede tener accesibilidad declarada pública o interna).
  • Los miembros de la interfaz tienen implícitamente accesibilidad pública declarada. No se permiten modificadores de acceso en las declaraciones de miembros de la interfaz.
  • Los miembros de la enumeración tienen implícitamente accesibilidad pública declarada. No se permiten modificadores de acceso en las declaraciones de miembros de enumeración.

(Tenga en cuenta que los tipos anidados se incluirían en las partes "miembros de la clase" o "miembros de la estructura" y, por lo tanto, su valor predeterminado será la visibilidad privada).

Jon Skeet
fuente
154
top level class: internal
method: private
members (unless an interface or enum): private (including nested classes)
members (of interface or enum): public
constructor: private (note that if no constructor is explicitly defined, a public default constructor will be automatically defined)
delegate: internal
interface: internal
explicitly implemented interface member: public!
John Buchanan
fuente
13
Esto no deja en claro que si una clase también es miembro (debido a que es un tipo anidado), su valor predeterminado es privado. Además, los miembros de una interfaz y enumeración son siempre públicos.
Jon Skeet
1
@niry No, no es privado. Es público Simplemente no tiene un espacio en el tipo de implementación, por lo que si class Foo : IFoo { IFoo.M() {} } ... Foo a = new Foo();no puede acceder Mcon él a.M(), sin embargo, puede acceder con él (a as IFoo).M(). (Consulte las especificaciones para obtener más información sobre los detalles)
M.Stramm
130

Respuesta corta: acceso mínimo posible (véase la respuesta de Jon Skeet).

Respuesta larga:

Tipos no anidados , enumeración y accesibilidad delegada ( solo puede tener accesibilidad interna o pública )

                     | Default   | Permitted declared accessibilities
------------------------------------------------------------------
namespace            | public    | none (always implicitly public)

enum                 | public    | none (always implicitly public)

interface            | internal  | public, internal

class                | internal  | public, internal

struct               | internal  | public, internal

delegate             | internal  | public, internal

Tipo anidado y accesibilidad de miembros

                     | Default   | Permitted declared accessibilities
------------------------------------------------------------------
namespace            | public    | none (always implicitly public)

enum                 | public    | none (always implicitly public)

interface            | public    | none

class                | private   | All¹

struct               | private   | public, internal, private²

delegate             | private   | All¹

constructor          | private   | All¹

interface member     | public    | none (always implicitly public)

method               | private   | All¹

field                | private   | All¹

user-defined operator| none      | public (must be declared public)

¹ Todos === público, protegido, interno, privado, protegido interno

² structs no pueden heredar de structs o clases (aunque pueden, interfaces), por lo tanto, protegido no es un modificador válido

La accesibilidad de un tipo anidado depende de su dominio de accesibilidad, que está determinado por la accesibilidad declarada del miembro y el dominio de accesibilidad del tipo que contiene inmediatamente. Sin embargo, el dominio de accesibilidad de un tipo anidado no puede exceder el del tipo que lo contiene.

Nota: CIL también tiene la provisión de protección e interna (a diferencia de la protección existente "o" interna), pero que yo sepa, esto no está disponible actualmente para su uso en C #.


Ver:

http://msdn.microsoft.com/en-us/library/ba0a1yw2.aspx
http://msdn.microsoft.com/en-us/library/ms173121.aspx
http://msdn.microsoft.com/en- us / library / cx03xt0t.aspx
(Hombre, me encantan los URI de Microsoft ...)

Ben Aston
fuente
12

Eche un vistazo a los modificadores de acceso (Guía de programación de C #)

Accesibilidad de clase y estructura

Las clases y estructuras que se declaran directamente dentro de un espacio de nombres (en otras palabras, que no están anidadas dentro de otras clases o estructuras) pueden ser públicas o internas. Interno es el valor predeterminado si no se especifica un modificador de acceso.

Los miembros de estructura, incluidas las clases y estructuras anidadas, se pueden declarar como públicas, internas o privadas. Los miembros de la clase, incluidas las clases y estructuras anidadas, pueden ser públicas, protegidas internas, protegidas, internas, privadas protegidas o privadas. El nivel de acceso para miembros de clase y miembros de estructura, incluidas clases y estructuras anidadas, es privado de forma predeterminada. No se puede acceder a los tipos anidados privados desde fuera del tipo que los contiene.

Las clases derivadas no pueden tener mayor accesibilidad que sus tipos base. En otras palabras, no puede tener una clase B pública que se derive de una clase interna A. Si esto se permitiera, tendría el efecto de hacer público A, porque todos los miembros protegidos o internos de A son accesibles desde la clase derivada.

Puede habilitar otros ensamblados específicos para acceder a sus tipos internos mediante el InternalsVisibleToAttribute. Para obtener más información, vea Asambleas de amigos.

Accesibilidad de miembros de clase y estructura

Los miembros de la clase (incluidas las clases y estructuras anidadas) se pueden declarar con cualquiera de los seis tipos de acceso. Los miembros de estructura no pueden declararse como protegidos porque las estructuras no admiten herencia.

Normalmente, la accesibilidad de un miembro no es mayor que la accesibilidad del tipo que lo contiene. Sin embargo, un miembro público de una clase interna puede ser accesible desde fuera del ensamblaje si el miembro implementa métodos de interfaz o anula los métodos virtuales que se definen en una clase base pública.

El tipo de cualquier miembro que sea un campo, propiedad o evento debe ser al menos tan accesible como el miembro mismo. Del mismo modo, el tipo de retorno y los tipos de parámetros de cualquier miembro que sea un método, indexador o delegado deben ser al menos tan accesibles como el miembro mismo. Por ejemplo, no puede tener un método público M que devuelva una clase C a menos que C también sea público. Del mismo modo, no puede tener una propiedad protegida de tipo A si A se declara como privado.

Los operadores definidos por el usuario siempre deben declararse como públicos y estáticos. Para obtener más información, consulte Sobrecarga del operador.

Los finalizadores no pueden tener modificadores de accesibilidad.

Otros tipos

Las interfaces declaradas directamente dentro de un espacio de nombres se pueden declarar como públicas o internas y, al igual que las clases y estructuras, las interfaces tienen un acceso interno predeterminado. Los miembros de la interfaz siempre son públicos porque el propósito de una interfaz es permitir que otros tipos accedan a una clase o estructura. No se pueden aplicar modificadores de acceso a los miembros de la interfaz.

Los miembros de enumeración son siempre públicos y no se pueden aplicar modificadores de acceso.

Los delegados se comportan como clases y estructuras. De manera predeterminada, tienen acceso interno cuando se declaran directamente dentro de un espacio de nombres y acceso privado cuando se anidan.

Adriaan Stander
fuente
8

La clase es interna por defecto.

  • Los miembros de la clase son privados por defecto.

La interfaz es interna por defecto.

  • Los miembros de la interfaz son públicos por defecto. (Las interfaces no nos permitirán especificar ningún tipo de accesibilidad a sus miembros).

    Nota: Si intenta especificar un especificador de acceso a los miembros de la interfaz, entonces muestra un error de compilación.

Struct es interno por defecto.

  • Los miembros de estructura son privados por defecto.
Kamala Hanchinal
fuente
5

Me gustaría agregar un enlace de documentación. Mira más detalles aquí .

ingrese la descripción de la imagen aquí

Asif Mushtaq
fuente
1
La clase es por defecto interna y no privada.
Baahubali
1
¿Dónde escribí la clase es privada?
Asif Mushtaq
Esta tabla es válida solo para tipos anidados.
BlueSilver
La clase es interna por defecto y la clase dentro del espacio de nombres no puede ser privada. pero la clase dentro de una clase (clase anidada) puede ser privada
Arun
El modificador de acceso de la interfaz es interno por defecto.
Kamala Hanchinal
4

La respuesta más simple es la siguiente .....

Todos los miembros en C # siempre toman el modificador MENOS accesible posible por defecto.

Es por eso que todas las clases de nivel superior en un ensamblaje son "internas" de forma predeterminada, lo que significa que son públicas para el ensamblaje en el que se encuentran, pero privadas o excluidas del acceso a ensamblajes externos. La única otra opción para una clase de nivel superior es pública, que es más accesible. Para los tipos anidados, todo es privado, excepto algunas raras excepciones, como miembros de enumeraciones e interfaces que solo pueden ser públicos. Algunos ejemplos. En el caso de las clases e interfaces de nivel superior, los valores predeterminados son:

clase Animal igual que clase interna Animal

interfaz Animal igual que la interfaz pública Animal

En el caso de las clases e interfaces anidadas (tipos internos), los valores predeterminados son:

clase Animal igual que clase privada Animal

interfaz Animal igual que la interfaz privada Animal

Si solo asume que el valor predeterminado es siempre el más privado, entonces no necesita usar un acceso hasta que necesite cambiar el valor predeterminado. Fácil.

Stokely
fuente
1

Interno es el modificador predeterminado

renjucool
fuente
0

Nivel de espacio de nombres: internal

Nivel de tipo: private

leppie
fuente