5

I have a method that accepts an IEnumerable-decimals and performance various math functions. I want to use the same method on an IEnumerable-int-. How do I implement this? For example to find a simple sum?

void Calculate<T>(IEnumerable <T> ListOFNumbers)
{
   int count= ListofNumbers.Count();
   ?sum=?;
}
Mitch Wheat
  • 295,962
  • 43
  • 465
  • 541
zsharp
  • 13,656
  • 29
  • 86
  • 152

4 Answers4

5

This is all freely available in MiscUtil. The Operator class provides access to generic arithmetic; and there are generic implementations (as extension methods) of Sum, Average, etc - and works with any type with suitable operators in addition to the primitives. So for example, you could use Sum with of Complex<T>, etc.

Note that it currently uses .NET 3.5; I did have a 2.0 version somewhere, but it isn't as tested....

A simplified example of sum is shown in the usage document:

public static T Sum<T>(this IEnumerable<T> source)
{
    T sum = Operator<T>.Zero;
    foreach (T value in source)
    {
        if (value != null)
        {
            sum = Operator.Add(sum, value);
        }
    }
    return sum;
}

Although IIRC the actual implementation has a bit more...

As an aside, note that dynamic (in .NET 4.0 / C# 4.0) supposedly supports operators, but we'll have to wait for the beta to see what it does. From my previous looks at dynamic in the CTP, I expect it to be a bit slower than the MiscUtil code, but we shall see.

Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
  • how much slower would this be than non-generic? – zsharp May 02 '09 at 16:49
  • I don't have metrics to hand - but it wasn't much slower at all. The `foreach` is still by far the dominant factor. – Marc Gravell May 02 '09 at 17:55
  • How the generic arithmetics offered by MiscUtil works internally? – Alex Yakunin Jul 05 '09 at 12:06
  • It uses Expression (.NET 3.5) to build the operators, compiles them to delegates, and caches them. I did have a 2.0 version kicking around somewhere. A *simplified* example of how it is implemented is shown here: http://www.yoda.arachsys.com/csharp/genericoperators.html – Marc Gravell Jul 05 '09 at 19:20
  • I've asked because we have similar framework: http://help.dataobjects.net/##DataObjects.Net_4-Essentials.chm/html/N_Xtensive_Core_Arithmetic.htm – Alex Yakunin Jul 09 '09 at 09:35
  • It's implemented differently (it uses our AssociateProvider to get some associate logic related to the particular type), but the result must be the same from the point of performance of a single operation. – Alex Yakunin Jul 09 '09 at 09:37
  • Does anyone know if the `MiscUtil` project is still around somewhere? – asgerhallas Mar 17 '20 at 10:14
0

You can use the IEnumerable.Sum function

Jeremy
  • 6,580
  • 2
  • 25
  • 33
0

This is purely looking and jumping around in reflector.


{
   IQueryable qt = ListofNumbers.AsQueryable();
   Console.WriteLine(qt.Sum());
}
shahkalpesh
  • 33,172
  • 3
  • 63
  • 88
0

You can use the built-in LINQ Aggregate(...) method to do this and many other more complicated calculations i.e.

int[] n = new int[] { 1, 2, 3, 4, 4, 5, 5, 6 };
int sum = n.Aggregate((x, y) => x + y);

as the lamdba is executed, once for each element in the enumeration the values of x,y are

0,1
1,2
3,3
6,4,
10,4,
14,5,
19,5
24,6

respectively and the final result is 30

With this you can use any aggregating function you want:

For example:

int[] n = new int[] { 1, 2, 3, 4, 4, 5, 5, 6 };
int count = n.Aggregate((x, y) => x + 1);

To simplify this there are built-in functions for common aggregates like Count and Max. Hope this helps

Alex

Alex James
  • 20,874
  • 3
  • 50
  • 49
  • What do you mean it doesn't work with generics? The Aggregate method is a generic, and the action you pass in can do anything you want, so if can work with any type, so yeah t + t won't work for every T but you can do anything in the action so why does that matter? – Alex James May 02 '09 at 16:56
  • The question starts with "IEnumerable ListOFNumbers". Given that *and just that*, try to use Aggregate to do a sum. You can't, because operators (+ etc) aren't supported for C# generics. At all. – Marc Gravell May 02 '09 at 17:57
  • Okay I see where you are coming from. I was just asserting that if you needed special operators you could implement them in the lambda you pass to the aggregate method. – Alex James May 02 '09 at 21:08