Creating Custom Aggregate Functions in LINQ



Jomo Fisher—Adriane asks whether it’s possible to create your own aggregate function like Sum, Avg, Count, etc. For object queries, the answer is yes. First, let’s look at the actual implementation of Sum:


 


public static int Sum(this IEnumerable<int> source) {


    int sum = 0;


    foreach (int v in source) sum += v;


    return sum;


}


 


You can see this yourself if you have the LINQ Preview for C# installed. This is a straightforward function except for the ‘this’ on the first parameter. This makes Sum an extension method. I talk about this in more detail here.


 


So let’s write our own method and call it.


 


using System;


using System.Collections.Generic;


 


static class Program {


    public static int SumSquares(this IEnumerable<int> source) {


        int sum = 0;


        foreach (int v in source) sum += (v*v);


        return sum;


    }


 


    static void Main(string[] args) {


        int [] i = new int [] {1,2,3};


        Console.WriteLine(i.SumSquares());


    }


}


 


For DLinq, there’s no way to do this today.


 


This posting is provided "AS IS" with no warranties, and confers no rights.


 

Comments (4)

  1. Gabe says:

    Odds are the sum of the squares of many ints will exceed the size on an int. Is it possible to do this:

    public static double SumSquares(this IEnumerable<int> source)

  2. Now, what we’re doing here with Project LINQ is that we are taking the concepts of query, step operations,…

  3. Dan Miser says:

    This doesn’t appear to work with Beta 2 and the C# LINQ Preview found on PDC disc 4. If I include the "this" modifier in SumSquares, I get tons of compile errors during build. If I remove it, I get the error "System.Array does not contain a definition for SumSqaures".

    I clearly remember Anders saying "this" was required, so I’m guessing it’s a difference between the bits we have and you have?

  4. PiersH says:

    alternatively:

    return source.Fold ((sum, x) => sum + x*x);

Skip to main content