6

我需要编写一些我称之为聚合容器的东西,它存储聚合,聚合本质上是采取对象集合并输出单个对象作为结果的操作。聚合的示例是:算术平均值、一组数字的中值、调和平均值等。这是一个示例代码。

var arithmeticMean = new Aggregation
        {
            Descriptor = new AggregationDescriptor { Name = "Arithmetic Mean" },
            Action = (IEnumerable arg) =>
            {
                double count = 0;
                double sum = 0;

                foreach (var item in arg)
                {
                    sum += (double)item;
                    count++;
                }

                return sum / count;
            }
        };

这是我的代码问题。我假设对象只是双倍的,因此进行了转换。如果他们不是双重的怎么办?如何确保允许我对两个对象求和?标准.Net程序集中是否有某种接口?我需要像 ISummable 这样的东西......或者我需要自己实现它(然后我必须包装所有原始类型,如 double、int 等来支持它)。

任何有关此类功能设计的建议都会有所帮助。

4

2 回答 2

3

看看Enumerable类方法——它有一组方法,它支持的每种类型都参数化了:

int Sum(this IEnumerable<int> source)
double Sum(this IEnumerable<double> source)
decimal Sum(this IEnumerable<decimal> source)
long Sum(this IEnumerable<long> source)
int? Sum(this IEnumerable<int?> source)
// etc

这是使方法参数成为“可总结”的唯一方法。

不幸的是,您不能使用泛型类型参数约束创建一些泛型方法,这将只允许 + 运算符重载的类型。.NET 中的运算符没有限制,运算符也不能是某些接口的一部分(因此它们是静态的)。因此,您不能将运算符与泛型类型的变量一起使用。

此外,如果您查看 .NET 原始类型定义,您将不会在这里找到任何可以帮助您的接口 - 仅实现了比较、格式化和转换:

public struct Int32 : IComparable, IFormattable, IConvertible, 
                      IComparable<int>, IEquatable<int>
于 2013-09-23T15:19:57.650 回答
0

Action您可以在类中修改您的属性,例如:

public Func<IEnumerable<double>, double> Action { get; set; }

所以它只会除外IEnumerable<double>并返回一个double结果。

于 2013-09-23T14:43:27.427 回答