【问题标题】:Implementing Average method in custom Queue wrapper在自定义队列包装器中实现平均方法
【发布时间】:2018-05-01 19:49:25
【问题描述】:

我有一个包装队列的自定义“可锁定”队列类。但是它缺少平均方法。

这是我尝试添加到下面源链接中列出的类的平均方法

public float Average()
        {
            lock (syncLock)
            {
                return queue.Average();
            }
        }

但在“队列”上出现以下错误

队列不包含“平均”和最佳的定义 方法扩展重载'Enumerable.Average(IEnumerable)' 需要“IEnumerable”类型的接收器

原文出处https://gist.github.com/jaredjenkins/5421892

【问题讨论】:

  • 你可以遍历队列并取平均值吗?
  • LINQ Average,不带参数,仅针对数字类型(int、float 等)的队列定义,并且您的队列是任意类型 T。
  • 你能用System.Collections.Concurrent.ConcurrentQueue代替自己滚动吗?
  • ConcurrentQue 在 Unity 中不可用。我需要的是一些具体的帮助,确切地说明如何将我的通用队列变成可以与 Average 一起使用的东西。

标签: c# .net unity3d queue average


【解决方案1】:

由于您清楚地在您的类中定义了一些字段或属性,您可以对其进行聚合以获得平均值,您可以选择在构造函数中定义一个 lambda 选择器函数,该函数将用于在执行时进行评估。唯一需要注意的是,字段/属性必须是公开可见的,因为它是在外部定义的。这个简单的类应该完成你想要做的事情。我确实注意到 linq.Average() 的默认返回类型是 double 而不是 float。所以我已经改变了这一点,否则它应该足够了。

public class QueueT<T>
{
    public QueueT(Func<T, int> avgSelector)
    {
        selector = avgSelector;
    }

    private Func<T, int> selector;
    private object syncLock = new object();
    private Queue<T> queue = new Queue<T>();

    public double Average()
    {
        lock (syncLock)
        {
            return (from item in queue select selector(item)).Average();
        }
    }

}

样本类型

public class Car
{
   //
   public int HP => 500;
}

然后当你创建一个实例时

public class RealImplementationandUseClass
{
    public RealImplementationandUseClass()
    {
        var q = new QueueT<Car>((c) => c.HP);
    }
}

这样您可以保证在编译时选择器可用于该类型,并且您不必对队列类的泛型类型施加约束。

【讨论】:

    【解决方案2】:

    好吧,从源代码看来,您可以通过这种方式实现该方法:

            public double Average()
            {
                return (from item in CopyToArray() select MakeNumberOrThrow(item)).Average();
            }
    
            private int MakeNumberOrThrow(object mightBeANumber)
            {
                return (int) mightBeANumber;
            }
    

    正如@Evk 在评论中提到的,为了使用 LINQ Average(),类型必须是数字。在 C# 中没有办法将泛型类型限制为数字,因此您必须以某种方式将类型转换为数字。显然,此方法或任何其他方法对于自定义 Queue 包装器中可能包含的所有类型都不安全。

    【讨论】:

    • 如果您知道类型,@fanuc_bob 的答案有效,并且它们不能转换为 int。
    猜你喜欢
    • 1970-01-01
    • 2020-05-02
    • 2012-09-12
    • 2015-11-30
    • 2018-09-12
    • 2017-06-07
    • 2021-01-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多