2010-12-23 25 views
8

Soy nuevo en C# y me pregunto si hay algo así como la herencia privada en C# (como en C++)?¿Herencia privada en C#?

Mi problema es el siguiente: que desea implementar una cola (nombrarlo SpecialQueue) con los siguientes cambios:

  1. La cola tiene un número máximo de elementos que se pueden almacenar en ella.
  2. Si la cola está llena e inserta un nuevo elemento, un elemento saldrá automáticamente de la cola (el primer elemento de la cola) y el nuevo elemento se insertará al final de la cola.
  3. Algunos métodos (como peek()) proporcionados por la cola no deben exponerse a los usuarios de SpecialQueue.

En C++ me gustaría ihnerit privado de la cola, exponer solo los métodos que quiero y cambiar otros a mi voluntad. Pero desafortunadamente, todos los métodos en cola no tienen el modificador "Anular" y no sé cómo lograr eso en C#.

¿Algún ayuda?

Saludos, Dan

+0

Me pregunto este modificador de la redefinición es simplemente 'modificador virtual' en C# o' override' modificador C# cuando usamos mientras se sobreescriben un virtual ¿método? – Tarik

Respuesta

15

Uso composición: incluyen un habitual Queue como un campo en el SpecialQueue. La herencia privada es en realidad algo muy similar a la composición.

Consulte http://www.parashift.com/c++-faq-lite/private-inheritance.html#faq-24.3 para la discusión.


implementación podría ser algo así:

public class SpecialQueue<T> 
{ 
    private int capacity; 
    private Queue<T> storage; 

    public SpecialQueue(int capacity) 
    { 
     this.capacity = capacity; 
     storage = new Queue<T>(); 
     // if (capacity <= 0) throw something 
    } 

    public void Push(T value) 
    { 
     if (storage.Count == capacity) 
      storage.Dequeue(); 
     storage.Enqueue(value); 
    } 

    public T Pop() 
    { 
     if (storage.Count == 0) 
      throw new SomeException("Queue is empty"); 
     return storage.Dequeue(); 
    } 

    public int Count 
    { 
     get { return storage.Count; } 
    } 
} 

Es necesario añadir más funciones/interfaces de si quieren SpecialQueue para apoyarlos. Sin embargo, no recomendaría implementar IEnumerable, porque esto permitiría Peek (que quiere prohibir).

+2

+1 Incluso si C# * tenía * herencia privada, esta seguiría siendo la respuesta correcta. :-) Gran enlace, también. –

+0

Aunque se pierda Linq al usar este enfoque. Puede que no sea necesario, pero podría ser una molestia ya que la clase es muy similar a una cola – RichK

+0

@RichK: el OP explícitamente quería una semántica bastante restringida: por ejemplo, 'Peek' no debería estar disponible. Con 'IEnumerable' estará fácilmente disponible a través de' FirstOrDefault'. – Vlad

4

podría implementar las mismas interfaces como Queue (o Queue<T>), tienen un Queue como un campo respaldo y exponer los métodos que necesita, que se limitará a envolver las llamadas al campo de respaldo.

Por ejemplo (han mantenido aplicación de ICollection en línea con Queue<T>)

public class SpecialQueue<T> : IEnumerable<T>, ICollection 
{ 
    private readonly Queue<T> _queue; 

    #region Constructors 

    public SpecialQueue() 
    { 
     _queue = new Queue<T>(); 
    } 

    public SpecialQueue(int capacity) 
    { 
     _queue = new Queue<T>(capacity); 
    } 

    public SpecialQueue(IEnumerable<T> collection) 
    { 
     _queue = new Queue<T>(collection); 
    } 

    #endregion 

    #region Methods 

    // implement any methods that you want public here... 

    #endregion 

    #region Interface Implementations 

    public IEnumerator<T> GetEnumerator() 
    { 
     return _queue.GetEnumerator(); 
    } 

    IEnumerator IEnumerable.GetEnumerator() 
    { 
     return _queue.GetEnumerator(); 
    } 

    public void CopyTo(Array array, int index) 
    { 
     ((ICollection) _queue).CopyTo(array, index); 
    } 

    public int Count 
    { 
     get { return _queue.Count; } 
    } 

    public object SyncRoot 
    { 
     get { return ((ICollection) _queue).SyncRoot; } 
    } 

    public bool IsSynchronized 
    { 
     get { return ((ICollection) _queue).IsSynchronized; } 
    } 

    #endregion 
} 
+0

+1 Por sugerir que 'SpecialQueue' implementa al menos algunas de las mismas interfaces como' Queue', lo que le da la posibilidad de ser inyectado en lugar de 'Queue'. –