C# 向扩展添加方法

C# 向扩展添加方法,c#,queue,extension-methods,C#,Queue,Extension Methods,我找到了一些代码来创建一个固定大小的队列。现在,我正试图添加一个Average方法,但我得到了一个信息: “队列”不包含“Average”的定义,最佳扩展方法重载“Queryable.Average(IQueryable)”需要类型为“IQueryable”的接收器 对于正常的队列我可以使用Average方法。为什么我不能在这里访问它 另外,先转换为数组或列表,然后取平均值也不起作用:queue.ToArray().average() 最后,为什么最好将此扩展包装到一个新类中,而不是通过执行公共

我找到了一些代码来创建一个固定大小的
队列
。现在,我正试图添加一个
Average
方法,但我得到了一个信息:

“队列”不包含“Average”的定义,最佳扩展方法重载“Queryable.Average(IQueryable)”需要类型为“IQueryable”的接收器

对于正常的
队列
我可以使用
Average
方法。为什么我不能在这里访问它

另外,先转换为数组或列表,然后取平均值也不起作用:
queue.ToArray().average()

最后,为什么最好将此扩展包装到一个新类中,而不是通过执行
公共类FixedSizeQueue:Queue
队列继承

public类FixedSizeQueue
{
专用队列;
公共固定大小(国际容量)
{
容量=容量;
队列=新队列(容量);
}
公共整数容量{get;私有集;}
公共整数计数{get{return queue.Count;}}
公共教育平均水平()
{
返回queue.Average();
}
公共空间清除()
{
queue.Clear();
}
公共T元素(内部i)
{
返回队列.ElementAt(i);
}
公共T排队(T项)
{
排队。排队(项目);
如果(queue.Count>容量)
{
return queue.Dequeue();
}
其他的
{
//如果希望它执行其他操作,例如返回'peek'值
//根据需要修改。
返回默认值(T);
}
}
公共T Peek()
{
return queue.Peek();
}
//不知从哪里弄来的。
公共IEnumerator GetEnumerator()
{
返回((IEnumerable)队列);
}
//IEnumerator IEnumerable.GetEnumerator()
//{
//返回((IEnumerable)队列);
//}
}

平均值
仅适用于以下类型:
十进制
整数
浮动

现在你的收藏是
T
,这是不可能平均的。 您需要在集合中使用选择器,并直接将其记录下来

例如,假设您有以下类

public class MyData
{
    public string Title {get;set;} = "";
    public double Value {get;set;} = 0d;
}
并假设您的队列为:

FixedSizeQueue<MyData> queue = new FixedSizeQueue<MyData>();
// add some data ...
queue.Enqueue(new MyData());

您不能使用此方法,因为它是
IEnumerable
的扩展方法(
Average
无参数是
IEnumerable
IEnumerable
等的一组扩展方法),并且您的
FixedSizeQueue
没有实现
IEnumerable
接口。如果您实施它(并将实施委托给
\u队列

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<string>(10);
var result = queue.Average(x => x.Length);
var queue=newfixedsizequeue(10);
var result=queue.Average(x=>x.Length);

Average()你期望如何
要处理你的类型
T
?你对@DavidG是什么意思?假设它是一个
队列
,字符串
foo
bar
的平均值是多少?最好创建扩展方法,而不是继承它,因为@DavidG提到的组合优先于继承原则,你不能使用使用
string
进行de>Average
,但您可以创建只与您的类型相关的扩展方法。啊,当然可以。我只需要它用于数字。因此,在进行平均之前,我首先需要检查它是否是浮点、双精度、整数等?也许我做错了什么,但它说:
'FixedSizeQueue[]'不包含'Average'的定义。
。当我在
FixedSizeQueue
中添加
public T Average(){return queue.Average();}
时,我得到了与我的问题相同的错误。@Roald你是如何得到
FixedSizeQueue[]
?这是队列数组,您需要
FixedSizeQueue
?@Roald我已经用
FixedSizeQueue
的完整修改实现进行了更新。您可以复制粘贴它并与您必须的内容进行比较,以发现问题。啊,是的,这是一个数组。对不起,我的错误。现在可以工作了。谢谢!
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();
    }
}
var queue = new FixedSizeQueue<float>(10);
var result = queue.Average();
var queue = new FixedSizeQueue<string>(10);
var result = queue.Average(x => x.Length);