【问题标题】:Private inheritance in C#?C#中的私有继承?
【发布时间】:2011-05-30 02:08:14
【问题描述】:

我是 C# 新手,想知道 C# 中是否有类似私有继承的东西(就像在 C++ 中一样)?

我的问题如下: 我想通过以下更改实现一个队列(将其命名为 SpecialQueue):

  1. 队列中可存储的项目数量已达到上限。
  2. 如果队列已满并且您插入新项目,则会自动从队列中弹出一个项目(队列中的第一个项目),并将新项目插入队列末尾。
  3. 队列提供​​的某些方法(例如 peek())不应暴露给 SpecialQueue 的用户。

在 C++ 中,我会从队列中私有化 ihnerit,只公开我想要的方法,并根据我的意愿更改其他方法。但不幸的是,队列中的所有方法都没有“Override”修饰符,我不知道如何在 C# 中实现。

有什么帮助吗?

问候, 丹

【问题讨论】:

  • 我想知道这个覆盖修饰符只是 C# 中的 virtual 修饰符,或者当我们在覆盖虚拟方法时使用 override 修饰符 C#?

标签: c# inheritance queue


【解决方案1】:

使用组合:在您的SpecialQueue 中包含一个常用的Queue 作为字段。私有继承实际上与组合非常相似。

请参阅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(您要禁止)。

【讨论】:

  • +1 即使 C# 私有继承,这仍然是正确的答案。 :-) 链接也很好。
  • 虽然你确实错过了使用这种方法的 Linq。这可能不是必需的,但可能会令人烦恼,因为该类与队列非常相似
  • @RichK:OP 明确需要非常有限的语义:例如,Peek 应该不可用。使用IEnumerable 可以通过FirstOrDefault 轻松获得。
  • 此解决方案有效,但问题是 SpecialQueue 不是队列,因此我无法保存其中某些元素实际上是 SpecialQueues 的队列数组。
  • @George:如果你想在使用Queue的地方使用SpecialQueue,你可以切换到公共继承()。但是像PeekEnqueue 这样的方法不是虚拟的,所以这是行不通的。 :-(
【解决方案2】:

您可以实现与Queue(或Queue&lt;T&gt;)相同的接口,将Queue 作为支持字段并公开您需要的那些方法,这将简单地包装对支持字段的调用。

例如(保持ICollection 的实现与Queue&lt;T&gt; 一致)

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
}

【讨论】:

  • +1 建议SpecialQueue 至少实现一些与Queue 相同的接口,使其有可能被注入以代替Queue
猜你喜欢
  • 1970-01-01
  • 2020-09-01
  • 2011-02-10
  • 2011-03-11
  • 2010-12-07
  • 2014-06-21
  • 1970-01-01
  • 2011-01-23
  • 2011-08-10
相关资源
最近更新 更多