Aggregation and how to check if we can sum objects

I need to write something that I call an aggregation container that stores aggregations, which are basically actions that take a collection of objects and output one object as a result. Examples of aggregations can be: Arithmetic mean, median of a set of numbers, harmonic mean, etc. Here is a sample code.

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

Here is my code problem. I assumed that the objects were just doubles and therefore did the conversion. What if they do not double? How can I make sure that I am allowed to sum two objects? Is there any interface for this in standard .Net assemblies? I need something like ISummable ... Or do I need to implement it myself (then I will have to wrap all the primitive types such as double, int, etc., to support it).

Any advice regarding the design of such features would be helpful.

+6
source share
2 answers

Take a look at the methods of the Enumerable class - it has many parameters parameterized by each supported type:

 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 

This is the only way to make the argument of the method β€œsummable”.

Unfortunately, you cannot create some general method with a general restrict type parameter , which will allow only types with the + operator to be overloaded. In .NET there are no restrictions for operators, nor can operators be part of some interface (therefore, they are static). Thus, you cannot use operators with variables of a general type.

Also, if you look at the definitions of primitive .NET types, you will not find any interface that can help you - only comparison, formatting and conversion are implemented:

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

You can change your Action property in the class, for example:

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

Thus, it will use only IEnumerable<double> and returns the result of double .

0
source

Source: https://habr.com/ru/post/954426/


All Articles