¿Cuál es el significado del modificador de acceso C # "protegido privado" planificado?

133

Como parte de la documentación de Roslyn en GitHub, hay una página llamada Estado de implementación de la función de idioma , con funciones de lenguaje planificadas para C # y VB.

Una característica que no podía entender era el private protectedmodificador de acceso:

private protected string GetId() {  } 

También hay una página de Notas de diseño de lenguaje C # , que explica muchas características nuevas, pero no esta.

Eric Lippert dijo en un comentario :

Su error es pensar en los modificadores como restricciones crecientes. Los modificadores de hecho siempre disminuyen las restricciones. Recuerde, las cosas son "privadas" por defecto; solo agregando modificadores los hace menos restringidos.

¿Cuál es el significado de private protected? ¿Cuándo podría usarlo?

Kobi
fuente
2
Tenga en cuenta que hay información al respecto en las notas de diseño del lenguaje VB .
Jesse Good
3
Es una asignación a MethodAttributes.FamANDAssem. C # tiene un extraño mapeo interno , utiliza (Privado | FamANDAssem). Y mapas internos protegidos a (Privado | Familia). Los atributos CLR son raros.
Hans Passant
22
Esta característica propuesta hará que mi comentario sea incorrecto.
Eric Lippert
El equipo de diseño de C # ha publicado una encuesta con una sintaxis alternativa sugerida para esta función. Algunos de estos son interesantes, como protected & internal, assembly protectedo proternal(espero que algunos de estos sean chistes). También está el hilo de discusión con algunas buenas ideas.
Kobi
1
¡La función ahora está marcada como retirada en el estado de implementación de la función de idioma! Personalmente, me gusta la idea de este nivel de acceso y creo que es una característica útil. Quiero usar el protegido para mantener mi código de acuerdo con el diseño de la clase, pero no quiero que otros escriban subclases hacky que tengan acceso a estos miembros. OMI, la mejor solución sería si pudiéramos escribir protected | internalyprotected & internal
Felix Keil

Respuestas:

98

De acuerdo con " Professional C # 2008 " de De Bill Evjen y Jay Glynn, página 1699:

privado protegido - "solo tipos derivados dentro del ensamblaje actual"

C ++ / CLI tiene una característica similar: definir y consumir clases y estructuras (C ++ / CLI)> Visibilidad de miembros :

private protected-o bien protected private- El miembro está protegido dentro de la asamblea pero privado fuera de la asamblea.

Gogutz
fuente
72
¿Entonces es "protegido e interno" en lugar de "protegido o interno"?
user541686
2
¿Ahora será posible que un miembro que sea accesible para las clases derivadas acepte o devuelva cosas de internaltipo sin requerir que el miembro esté expuesto a todo en la asamblea?
supercat
¡Gracias! No pensé en eso. De hecho, tengo casos en los que hubiera usado ese modificador y volviera a funcionar internal.
Kobi
3
La existencia de esta propuesta / característica parece sugerir que la internalvisibilidad (relacionada con el lugar donde se define la clase) es realmente ortogonal a public/ protected/ privatevisibilidad (relacionada con la herencia) y que, tal vez, internaldebería ser su propio modificador separado de public/ protected/ private.
jpmc26
1
@jww: no estoy muy familiarizado con Java, pero por lo que sé packageen Java se parece más al espacio de nombres en C #.
Gogutz
187

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

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

private protected: - agregado en C # 7.2
ingrese la descripción de la imagen aquí

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

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

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

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

Kobi
fuente
3
Imagen de origen: Access Modifiers.pdn . Usé el llamado Paint.Net .
Kobi
9
¿Dónde han estado estos diagramas toda mi vida (C #)? Son excelentes, ¡gracias!
Jon Peterson
28

Esto es solo para proporcionar un gráfico (hecho con http://ashitani.jp/gv/ ) de los diferentes niveles de accesibilidad (las imágenes no caben en los comentarios).

diagrama de diagrama de niveles de acceso de C #

Cada flecha significa "es más restrictivo que".

Los nombres son CLR Private, FamilyANDAssembly, Assembly, Family, FamilyORAssembly, Public.


Edición mucho más tarde: resultó que este nuevo y agradable nivel de acceso (con un nombre realmente pobre) finalmente no se incluyó en C # 6.0. Solo es compatible con C # 7.2 (y veo que actualizó sus "etiquetas" de preguntas).

Jeppe Stig Nielsen
fuente
Podría ser solo yo, pero las flechas parecen ir en la dirección 'menos restrictiva que'.
acarlon
44
@acarlon Sí, entonces a → ben el diagrama significa " aes más restrictivo que b", por lo que puede "leer" la flecha como "es más restrictivo que" (eso fue lo que intenté explicar), por lo que la flecha apunta en el menos restrictivo " dirección". La convención opuesta para las flechas podría haber sido igual de buena, por cierto, pero tuve que elegir una convención.
Jeppe Stig Nielsen
10

Es solo una suposición, pero por un nombre que posiblemente puedas adivinar es una versión más restringida de protected(o una versión más relajada privatesi lo deseas). Y solo una variante razonable es restringir el protectedcomportamiento al ensamblaje.

Uso posible: entonces desea tener protecteduna implementación interna, pero no para usos externos (y no desea sellar la clase).

PD: siempre existió en CLR, pero no en C # . Es una combinación de protected y internal , cita:

CLR también admite el tipo de acceso "Familia y ensamblaje". Esto significa que se puede acceder al método desde el tipo de declaración, los tipos anidados y derivados, pero solo si se declaran en el mismo ensamblado. Bueno, aparentemente el equipo de C # no pensó en esto como una característica muy útil, por lo que no es compatible con este lenguaje.

Petr Abdulin
fuente
+1 para el comentario de CLR: actualmente paso tanto tiempo en C # y tan poco en los otros lenguajes .NET que a veces olvido que no son lo mismo.
brichins
@DarrelHoffman gracias por señalar!
Mezclé
5

"Puede ser" solo visible para las subclases que están en el mismo ensamblado. Esto lo hace un poco restringido que protected.

Mehmet Ataş
fuente
1

Consulte las especificaciones de la función "privada protegida":

El significado intuitivo de privado protegido es "accesible dentro de este ensamblado por tipos derivados de la clase que lo contiene".

Julien Couvreur
fuente