2010-04-01 17 views
50

Ok, entonces esta puede ser una pregunta un poco tonta, y ciertamente hay una respuesta obvia, pero tenía curiosidad si había olvidado alguna sutileza aquí.Miembros públicos e internos en una clase interna?

¿Hay alguna diferencia en términos de visibilidad/usabilidad entre un miembro public declarados en una clase internal y un miembro de internal declarado en una clase internal?

es decir, entre

internal class Foo 
{ 
    public void Bar() 
    { 
    } 
} 

y

internal class Foo 
{ 
    internal void Bar() 
    { 
    } 
} 

Si usted declaró el método como public y también virtual, y luego sobrescritos en una clase derivada que es public, la razón para usar este modificador es claro. Sin embargo, ¿es esta la única situación ... me estoy perdiendo algo más?

+2

_Si declaraste el método como público y también virtual, y luego lo anulaste en una clase derivada que es public_ ** meeeep! **: No puedes aumentar la visibilidad, solo al revés: puedes crear un clase derivada de una clase pública que es interna (o incluso anidada y privada) – springy76

+2

Googlers toma nota: Esta casi [duplicada] [pregunta] (http://stackoverflow.com/questions/9302236/why-use-a-public-method -in-a-internal-class/9302642 # 9302642) contiene otra respuesta particularmente excelente. –

Respuesta

47

Considere este caso:

public interface IBar { void Bar(); } 
internal class C : IBar 
{ 
    public void Bar() { } 
} 

Aquí C.Bar no se puede marcar como interna; Hacer esto es un error porque C.Bar se puede acceder por una persona que llama de D.GetBar():

public class D 
{ 
    public static IBar GetBar() { return new C(); } 
} 
+1

Gracias Eric, este es otro buen caso. De modo que la implementación efectiva de la interfaz y la herencia de clases son las razones para permitir el modificador 'public' o' internal' en una clase 'internal'. En otros casos, son equivalentes a lo que parecería. – Noldorin

+8

Eric también responde una pregunta casi idéntica en: http://stackoverflow.com/a/9302642/398015 Hay detalles adicionales en su publicación que agregan bastante sustancia a la respuesta anterior. – Chris

0

public miembros de una clase internal puede anular publicpublic miembros de las clases base y, por lo tanto, ser un poco más expuesta ... sea indirectamente.

29

Un miembro public sigue siendo internal cuando en una clase internal.

From MSDN:

The accessibility of a member can never be greater than the accessibility of its containing type. For example, a public method declared in an internal type has only internal accessibility

creo que de esta manera, me habría acceso a una propiedad en public ....? Una clase que no puedo ver? :)

La respuesta de Eric es muy importante en este caso, si está expuesta a través de una interfaz y no directamente hace hacer la diferencia, solo depende si se encuentra en esa situación con el miembro con el que está tratando.

+0

Sí, esta era exactamente mi idea, excepto en el caso que Eric señaló (así como también en mi pregunta original). – Noldorin

+0

También hace la diferencia cuando usa la reflexión. Los métodos predeterminados sin parámetros como Type.GetMethods() solo devuelven miembros públicos. Y el método público dentro de la clase interna todavía sabe que es público. – springy76

+1

"La accesibilidad de un miembro nunca puede ser mayor que la accesibilidad de su tipo contenedor". Si bien esto es cierto para algunos casos, un miembro 'público' de una clase' privada' es claramente un alcance más amplio que un miembro 'privado' de una clase' privada' (el primero es un proyecto completo, el último solo de clase). – Deanna

1

Si se trata de la reflexión que importe si el miembro es pública o no:

Por ejemplo incluso podría pasar una clase privada anidada a un enlace WPF y el enlace funcionaría contra las propiedades públicas como de costumbre.

1

Acabo de enfrentar con otro ejemplo donde es diferencia entre esos dos, cuando se usa desde XAML en WPF.

XAML:

<Button Tag="{x:Static vm:Foo+Bar.e1}" /> 

Código con internal enumeración compila correctamente:

internal class Foo 
{ 
    internal enum Bar 
    { 
     e1, 
     e2, 
    } 
} 

Pero sorprendentemente cambiándolo a public resultados en el error:

internal class Foo 
{ 
    public enum Bar 
    { 
     e1, 
     e2, 
    } 
} 

El último ejemplo produce error de compilación :

error MC3064: Only public or internal classes can be used within markup. 'Bar' type is not public or internal.

Desafortunadamente, no puedo explicar qué pasa con public en este caso. Mi suposición es "solo porque WPF funciona de esa manera". Simplemente cambie el modificador de la clase anidada a internal para eliminar el error.

+0

¡Gracias por esto! Nunca adivinaría qué pasaba con mi XAML – torvin

Cuestiones relacionadas