Частное наследование в C #? - PullRequest
       10

Частное наследование в C #?

8 голосов
/ 23 декабря 2010

Я новичок в C # и удивляюсь, есть ли что-то вроде частного наследования в C # (как в C ++)?

Моя проблема заключается в следующем: я хочу реализовать очередь (назовите ее SpecialQueue) с помощьюследующие изменения:

  1. В очереди есть максимальное количество элементов, которые могут быть сохранены в ней.
  2. Если очередь заполнена, и вы вставляете новый элемент, один элемент будетавтоматически выскакивает из очереди (первый элемент в очереди), и новый элемент будет вставлен в конец очереди.
  3. Некоторые методы (например, peek ()), предоставляемые очередью, не должны отображатьсяпользователям SpecialQueue.

В c ++ я бы приватно ihnerit из очереди, выставлял только те методы, которые я хочу, и изменял другие на свое усмотрение.Но, к сожалению, все методы в очереди не имеют модификатора «Override», и я не знаю, как этого добиться в C #.

Любая помощь?

С уважением, Дан

Ответы [ 2 ]

15 голосов
/ 23 декабря 2010

Используйте композицию: включите обычное Queue в качестве поля в вашем SpecialQueue.Частное наследование на самом деле очень похоже на композицию.

См. http://www.parashift.com/c++-faq-lite/private-inheritance.html#faq-24.3 для обсуждения.


Реализация может выглядеть примерно так:

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; }
    }
}

Вам нужно добавить больше функций / интерфейсов, если вы хотите, чтобы SpecialQueue поддерживал их.Однако я бы не рекомендовал реализовывать IEnumerable, потому что это позволило бы Peek (что вы хотите запретить).

4 голосов
/ 23 декабря 2010

Вы можете реализовать те же интерфейсы, что и Queue (или Queue<T>), иметь Queue в качестве вспомогательного поля и предоставить те методы, которые вам нужны, которые просто обернут вызовы в вспомогательное поле.

Например (сохранили реализацию ICollection в соответствии с 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
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...