2009-08-03 16 views
19

He estado refacturando la base de código del proyecto en el que estoy actualmente para que las clases/interfaces que no son útiles más allá de los límites del ensamblado se declaren como internas (en lugar de públicas) . Pero me he encontrado con un problema con el siguiente código:Cómo implemento miembros de interfaces internas

internal interface IFirstInterface 
{ 
    ... 
} 

internal interface ISecondInterface 
{ 
    IFirstInterface First{ get; } 
    ... 
} 

public class Implementer : ISecondInterface 
{ 
    public IFirstInterface First {get; private set;} 
    ... 
} 

Mis preguntas:

  1. ¿Por qué los miembros de las interfaces internas tienen que ser aplicadas públicamente? Si implementa la interfaz en una clase interna, ¿no deberían los miembros implementados ser internos? Esto no es un gran problema ya que los miembros de la interfaz no serán accesibles públicamente de todos modos, dado que la clase es interna. Parece contra intuitivo.

  2. El principal problema es con el escenario anterior ya que no puede tener un captador pública para IFirstInterface ya que es supuestamente un ejemplo de interfaz interna me sale el siguiente error del compilador:

accesibilidad inconsistente : propiedad tipo 'IFirstInterface' es menos accesible que propiedad 'Implementer.First'

es allí e cualquier forma de evitar esto?

Nota: Me doy cuenta de que probablemente haya poco valor en este ejercicio de refactorización, pero pensé que sería una buena forma de entender más profundamente las implicaciones del modificador interno.

+0

Si su opción, puede moverse por la limitación de los métodos de interfaz siendo pública mediante el uso de una clase base abstracta en su lugar. –

Respuesta

45

Solo para tener en cuenta: el código que en realidad proporcionó hace compilar, porque Implementer es una clase interna. El problema surge cuando Implementer es público.

La manera alrededor de esto es el uso de implementación de interfaz explícita:

public class Implementer : ISecondInferface 
{ 
    private IFirstInterface first; 
    IFirstInterface ISecondInterface.First { get { return first; } } 
} 

No se puede tener en la incubadora allí, porque va a implementar de manera explícita la interfaz que no define la incubadora. Usted podría hacer esto como una alternativa:

public class Implementer : ISecondInterface 
{ 
    internal IFirstInterface First { get; private set; } 
    IFirstInterface ISecondInterface.First { get { return First; } } 
} 

Es desafortunado que las interfaces internas tienen miembros públicos - no complicar las cosas como esta. Sería extraño que una interfaz pública tenga un miembro interno (¿qué sería interno para el implementador o el declarante?) Pero para las interfaces internas tiene mucho más sentido.

+0

Ah, correcto. Editaré mi pregunta para que sea menos confusa para los lectores. ¡Gracias! – jpoh

10

¿Por qué los miembros de las interfaces internas deben implementarse públicamente?

Cuando define una interfaz, no define el nivel de acceso para los miembros, ya que todos los miembros de la interfaz son public. Incluso si la interfaz como tal es internal, los miembros todavía se consideran public. Cuando realiza una implementación implícita de dicho miembro, la firma debe coincidir, por lo que debe ser public.

En cuanto a la exposición del captador, sugeriría hacer una explícita implementación de la interfaz en su lugar, y la creación de una propiedad internal para exponer el valor:

internal IFirstInterface First { get; private set; } 

IFirstInterface ISecondInterface.First 
{ 
    get { return this.First; } 
} 
7

Sé que este post es un par de años, pero creo que vale la pena señalar que se puede implementar una interfaz interna en una clase pública, consulte los siguientes enlaces:

http://forums.create.msdn.com/forums/p/29808/167820.aspx
http://msdn.microsoft.com/en-us/library/aa664591%28VS.71%29.aspx

Un ejemplo del primer enlace:


internal interface ISecretInterface 
{ 
    string Property1 { get; } 
} 

public class PublicClass : ISecretInterface 
{ 
    // class property 
    public string Property1 
    { 
     get { return "Foo"; } 
    } 

    // interface property 
    string ISecretInterface.Property1 
    { 
     get { return "Secret"; } 
    } 
} 
+0

¿En qué se diferencia su respuesta de 2011 de las dos respuestas de 2009? –

+2

Honestamente, no sé y puedo ver por qué lo habría agregado, aunque recuerdo haberlo hecho. No agrega nada y he estado tratando de resolverlo mirando el historial de revisión para ver si había alguna pista, pero aún nada. Tal vez estaba teniendo un día tonto. – Robert

+0

Por alguna razón, esta respuesta es más fácil de consumir que las anteriores porque la explicación al comienzo de la respuesta aborda mi situación y coincide con lo que busqué en Google. Así que gracias por indicar claramente que las clases públicas pueden implementar interfaces internas de una manera fácil de consumir ;-). – binki

Cuestiones relacionadas