开发者

Private inheritance in C#?

I'm new to C# and wondered if there is something like private inheritance in C# (like in C++) ?

My problem is as follows: I want to implement a queue (name it SpecialQueue) with the following changes:

  1. The queue has a maximum number of items that can be stored in it.
  2. If the queue is full and you insert a new开发者_StackOverflow item, one item will be automatically poped out of the queue (the first item in the queue) and the new item will be inserted to the end of the queue.
  3. Some methods (such as peek()) provided by queue should not be exposed to SpecialQueue's users.

In c++ I would private ihnerit from queue, expose only the methods I want to and change others to my will. But unfortunatley, all methods in queue don't have the "Override" modifier and I don't know how to achieve that in C#.

Any help?

Regards, Dan


Use composition: include a usual Queue as a field in your SpecialQueue. Private inheritance is actually something very similar to composition.

See http://www.parashift.com/c++-faq-lite/private-inheritance.html#faq-24.3 for discussion.


Implementation could be something like that:

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

You need to add more functions/interfaces if you want SpecialQueue to support them. I would however not recommend to implement IEnumerable, because this would allow Peek (which you want to prohibit).


You could implement the same interfaces as a Queue (or Queue<T>), have a Queue as a backing field and expose those methods that you need to, which will simply wrap the calls to the backing field.

For example (have kept implementation of ICollection in line with 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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜