首页 > 解决方案 > 向扩展添加方法

问题描述

我在这里找到了一些使 aQueue具有固定大小的代码。现在我正在尝试为此添加一个方法,但我收到消息:Average

'Queue' 不包含'Average' 的定义,并且最佳扩展方法重载'Queryable.Average(IQueryable)' 需要'IQueryable' 类型的接收器

对于正常情况Queue,我可以使用该Average方法。为什么我不能在这里访问它?

同样首先转换为数组或列表,然后取平均值不起作用:queue.ToArray().Average().

Queue最后,为什么将这个扩展包装在一个新类中而不是通过做继承更好public class FixedSizeQueue<T> : Queue<T>

public class FixedSizeQueue<T>
{
    private Queue<T> queue;

    public FixedSizeQueue(int capacity)
    {
        Capacity = capacity;
        queue = new Queue<T>(capacity);
    }

    public int Capacity { get; private set; }

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

    public T Average()
    {
        return queue.Average();
    }

    public void Clear()
    {
        queue.Clear();
    }

    public T ElementAt(int i)
    {
        return queue.ElementAt(i);
    }

    public T Enqueue(T item)
    {
        queue.Enqueue(item);
        if (queue.Count > Capacity)
        {
            return queue.Dequeue();
        }
        else
        {
            //if you want this to do something else, such as return the `peek` value
            //modify as desired.
            return default(T);
        }
    }

    public T Peek()
    {
        return queue.Peek();
    }

    // Got it from somewhere, don't know where.
    public IEnumerator<T> GetEnumerator()
    {
        return ((IEnumerable<T>)queue).GetEnumerator();
    }

    //IEnumerator IEnumerable.GetEnumerator()
    //{
    //    return ((IEnumerable<T>)queue).GetEnumerator();
    //}
}

标签: c#queueextension-methods

解决方案


你不能使用这个方法,因为它的扩展方法IEnumerable<T>Average没有参数是一组扩展方法IEnumerable<int>IEnumerable<double>等等)并且你FixedSizeQueue没有实现IEnumerable<T>接口。如果您实现它(并将实现委托给_queue

public class FixedSizeQueue<T> : IEnumerable<T> {
    private Queue<T> queue;

    public FixedSizeQueue(int capacity) {
        Capacity = capacity;
        queue = new Queue<T>(capacity);
    }

    public int Capacity { get; private set; }

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

    public void Clear() {
        queue.Clear();
    }

    public T Enqueue(T item) {
        queue.Enqueue(item);
        if (queue.Count > Capacity) {
            return queue.Dequeue();
        }
        else {
            //if you want this to do something else, such as return the `peek` value
            //modify as desired.
            return default(T);
        }
    }

    public T Peek() {
        return queue.Peek();
    }

    public IEnumerator<T> GetEnumerator() {
        return ((IEnumerable<T>) this.queue).GetEnumerator();
    }

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

然后你就可以Average像往常一样使用了:

var queue = new FixedSizeQueue<float>(10);
var result = queue.Average();

对于非数字类型的队列,您仍然可以使用Average接受参数的重载:

var queue = new FixedSizeQueue<string>(10);
var result = queue.Average(x => x.Length);

推荐阅读