2010-01-07 10 views
7

Estaba teniendo el problema de querer que una propiedad tenga un getter interno y un setter protegido, como se describe en this question, y pensé que lo resolví haciendo lo siguiente:getter interno C#, setter protegido con un parámetro de clase interno

public class Accessor : AccessorBase 
{ 
    private Connection _connection; 

    protected void setConnection(Connection value) 
    { 
     _connection = value; 
    } 

    internal Connection GetConnection() 
    { 
     return _connection; 
    } 
    ... 
} 

Sin embargo, ahora estoy recibiendo este error:

Inconsistent accessibility: parameter type 'Connection' is less accessible than method 'setConnection(Connection)'

esto es porque tengo internal class Connection. Preferiría no hacer Connection una clase pública, mientras que Accessornecesita para ser público, así que ¿cómo puedo evitar este error mientras mantengo un getter interno y un setter protegido?

Respuesta

2

...any protected members are visible outside the assembly and can't use an internal type.

-Pent Ploompuu's answer

Una forma de evitar esto es hacer Connection pública al tiempo que todos sus métodos de instancia interna y constructores.

+0

+1 para una solución excelente. En .NET BCL ocasionalmente ves clases sin ningún método: todo es privado o interno. – Abel

+1

acaba de golpear esta pared. es un catch 22 ... o bien permite la visibilidad de sus clases internas [pero de lo contrario está vacío para el mundo externo] o permite que otras clases internas configuren algo, solo las clases derivadas deberían ... humnnnn ... –

1

Si la clase Connection es interna, una clase que se deriva de Accessor no podrá llamar a setConnection protegido ya que no tiene acceso a Connection.

Si se va a proteger setConnection, Connection tendrá que ser público.

+0

¿Por qué no, si la clase derivada de Accessor está en el mismo espacio de nombres/proyecto que Accessor y Connection? –

+2

"interno protegido" significa "protegido" o "interno", lo que significa que es menos restrictivo que solo "protegido". –

+0

@Sarah: a C# no le importa de dónde sacas actualmente la clase. Todo lo que le dice es que está tratando de tener una función protegida en una clase pública que usa una clase interna. Esto es ilegal ya que cualquier clase derivada de su clase pública no necesariamente tendrá acceso a Connection. – Coincoin

8

Desafortunadamente C# no soporta "y protegidas internas" modificadores de acceso (sólo "interno o protegidos" es compatible), lo que significa cualquier protected miembros son visibles fuera del conjunto y no pueden utilizar un tipo interno .
Usar internal en lugar de protected sería la solución más lógica.

Y podría vote at Microsoft Connect para que algún día se agregue a C#.

+2

Hm, podría ser capaz de evitarlo haciendo pública la 'Conexión' y haciendo que todos sus métodos de instancia y constructores sean 'internos' ... –

+0

Sí, esa podría ser una solución aceptable. –

+0

+1, gracias por aclarar eso, Pent, publicaría esto en el antiguo hilo de ideas erróneas si no hubiera sido demasiado completo. (Esto me pareció un poco reconfortante: http://haacked.com/archive/2007/10/29/what-does-protected-internal-mean.aspx, además de que tiene un nugget interesante que indica que CLR admite y- las dos visibilidades; C# simplemente no tiene la sintaxis.) –

0

Lo sentimos, si necesita esa configuración exacta, tendrá que hacer que su clase Connection sea pública.

0

Desafortunadamente no puedes hacer eso. Como el Connection es interno, algunas clases derivadas de Accessor de otro ensamblado no podrían ver Connection, aunque marque el setter como protected internal no resolvería nada.

Su única esperanza es hacer pública la conexión de clase.

+0

interfaces sería su otra esperanza también ... :) –

+1

@Stan: y por 'su' quieres decir 'ella', ¿verdad? ;) –

5

Cree una interfaz pública IConnection que implemente su objeto interno Connection. Haga que sus métodos GetConnection y SetConnection acepten y devuelvan IConnection en lugar de Connection.

Principios básicos SOLID vuelven a ganar.

+2

+1 Esto era * exactamente * de lo que estaba escribiendo (sin la patada lateral) ... – Abel

+1

+1 respuesta increíble ... hizo mi sonrisa –

+2

¿Y qué tipo de métodos/propiedades debería 'IConnection' requerir? Cualesquiera que sean los métodos públicos en 'Conexión'? –

0

Coincoin is correct, Accessor es una clase pública que cualquiera puede obtener de ella, esto significa también de un ensamblaje diferente. Esa clase derivada ahora tiene un método protegido al que debes pasar una clase interna (de otro ensamblado). Esto nunca funcionaría.

Se deberán bien Accessor interna o Connection pública, o mejor aún siguen Randolphos answer

Aquí es un ejemplo de código del problema

Asamblea 1

//this class is only visible in Assembly 1 
internal class Connection 
{ 

} 
public class Accessor 
{ 
    protected void SetConnection(Connection con) { } 
} 

Asamblea 2 - tiene referencia a la Asamblea 1

//possible because Accessor is public 
DerivedAccessor : Accessor 
{ 
    void SomeMethod() 
    { 
     this.SetConnection(????) // you can't pass Connection, its not visible to Assembly2 
    } 
} 
Cuestiones relacionadas