2012-09-19 12 views
6

Tengo una biblioteca de clases con 2 clases públicas que heredan de una clase abstracta. En la clase abstracta, tengo un campo protegido que solo debería ser accesible para las clases heredadas. El tipo utilizado para el campo es el de una clase interna.Uso de un tipo interno utilizado como campo protegido

Por ejemplo tengo:

internal class MyInternalClass 
{ 
    ... 
} 

public abstract class MyAbstractClass 
{ 
    protected MyInternalClass myField; 
} 

Ahora entiendo que esto no funcionará porque si una de las clases derivadas de la clase MyAbstract se extiende fuera de la asamblea, el acceso a myField sería ilegal.

Mi pregunta es cómo puedo hacer que las cosas funcionen mientras mantengo MyInternalClass interno (no debería ser accesible fuera del ensamblaje) y permitiendo que las clases dentro del ensamblaje extiendan MyAbstractClass con acceso a myField?

+4

¿Debe ser la última clase ('abstracta')' pública'? –

+0

Sí, debe ser. Las 2 clases que lo extienden son públicas. – zaq

+0

posible duplicado de [¿Cómo hacer una propiedad protegida Y interna en C#?] (Http: // stackoverflow.com/questions/941104/how-to-make-a-property-protected-and-internal-in-c) – nawfal

Respuesta

5

Crea una interfaz pública que requiere MyAbstractClass y MyInternalClass implementos.

Algo como esto para que pueda tener sea MyInternalClass por defecto, pero inyectar nuevo comportamiento si es necesario (por ejemplo, burlándose):

internal class MyInternalClass : IMyInterface 
{ 
} 

public interface IMyInterface 
{    
} 

public abstract class MyAbstractClass 
{ 
    protected IMyInterface myField; 

    protected MyAbstractClass(IMyInterface required = null) 
    { 
     myField = required ?? new MyInternalClass(); 
    } 
} 
+2

También puede almacenar la referencia de clase interna en un campo privado, luego proporcionar una propiedad protegida exponiéndola como el público interfaz. Esto tiene el beneficio adicional de permitirle restringir aún más el acceso a la clase interna (a través de la interfaz) a solo lo que necesitan los derivers de MyAbstractClass. También le da flexibilidad si alguna vez se implementa esta interfaz de manera diferente (por ejemplo, descomponiendo su funcionalidad en dos clases auxiliares en lugar de una, por ejemplo). –

+0

@DanBryant: Muy cierto. Buena sugerencia. –

0

No se puede. Si se deriva MyAbstractClass en una clase externa, es necesario conocer MyInternalClass.

Si necesita pensar en cosas como esta, el diseño podría necesitar una nueva versión.

0

Haga el campo myFieldinternal protected.

También tienes que hacer MyAbstractClass interno. No hay forma de que pueda ser pública si hereda de una clase interna. Si la clase tiene que ser pública, tiene que haber una forma de evitarla: por ejemplo, cree una interfaz que exponga la funcionalidad de MyInternalClass que necesitan las clases heredadas.

0

usted está en necesidad de una palabra clave que especifica protegido "y" interna en lugar de protegida "o" interno. Tal palabra clave no existe (a partir de C# 5.0). Podrían agregarlo en versiones posteriores.

Hay muchos hilos en esto aquí. Se por ejemplo question 5596338.

ADEMÁS: Ahora me han llegado con esta "solución":

public abstract class MyAbstractClass 
{ 
    protected class AccessMyFieldHelper 
    { 
     internal MyInternalClass this[MyAbstractClass mac] 
     { 
      get { return mac.myField; } 
      set { mac.myField = value; } 
     } 
    } 
    protected static readonly AccessMyFieldHelper AccessMyField = new AccessMyFieldHelper(); 

    private MyInternalClass myField; 
} 

El myField es ahora private, pero no se protege el acceso al mismo a través de la AccessMyField. Como es un indexador, deberá usar los corchetes [].

¿Qué opinas? ¿Se puede hacer esto más bellamente?

Cuestiones relacionadas