Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Aggregation and how to check if we can sum objects

I need to write something I call Aggregation Container, which stores Aggregations, which are essentially Actions that take a collection of objects and output a single object as a result. Examples of Aggregations would be: Arithmetic Mean, Median of a set of numbers, Harmonic Mean etc. Here's 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's my problem with the code. I have assumed that the objects were just double and hence made a conversion. What if they're not double? How can I make sure that I'm allowed to sum two objects? Is there some kind of interface for that in standard .Net assemblies? I need something like ISummable... Or do I need to implement it myself (then I will have to wrap all primitive types like double, int, etcetera to support it).

Any advice regarding the design of such functionality will be helpful.

like image 486
george.zakaryan Avatar asked Sep 23 '13 14:09

george.zakaryan


1 Answers

Take a look on Enumerable class methods - it has set of methods parametrized with each type it supports:

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

That's the only way to make method argument to be 'summable'.

Unfortunately you can't create some generic method with generic type parameter constraint, which will allow only types with +operator overloaded. There is no constraint for operators in .NET, also operators cannot be part of some interface (thus they are static). So, you can't use operators with variables of generic type.

Also if you will look on .NET primitive types definitions, you will not find any interface which can help you here - only comparing, formatting, and converting are implemented:

public struct Int32 : IComparable, IFormattable, IConvertible, 
                      IComparable<int>, IEquatable<int>
like image 130
Sergey Berezovskiy Avatar answered Sep 18 '22 09:09

Sergey Berezovskiy