聚合以及如何检查是否可以对对象求和

时间:2013-09-23 14:34:59

标签: c# .net interface aggregation

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

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,etcetera以支持它)。

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

2 个答案:

答案 0 :(得分: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

这是使方法参数成为'summable'的唯一方法。

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

此外,如果您查看.NET基元类型定义,您将找不到任何可以帮助您的界面 - 仅实现比较,格式化和转换:

public struct Int32 : IComparable, IFormattable, IConvertible, 
                      IComparable<int>, IEquatable<int>

答案 1 :(得分:0)

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

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

因此只有IEnumerable<double>除外,并返回double结果。