Freigeben über


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

  • Anonymous
    September 15, 2005
    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)
  • Anonymous
    September 16, 2005
    Now, what we're doing here with Project LINQ is that we are taking the concepts of query, step operations,...
  • Anonymous
    September 17, 2005
    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?
  • Anonymous
    September 19, 2005
    alternatively:

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