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