tags:

views:

312

answers:

2

I've got some code which accepts a DataTable as a parameter and calculates the total of several of the columns in the DataTable. I thought it might be nice to be able to pass in a lambda expression which would perform a filter on the column I'm totaling.

Here's a portion of the code:

public TrafficTotals CalculateTotals(DataTable table)
{
    TrafficTotals total = new TrafficTotals();
    total.TotalTraffic = table.AsEnumerable().Sum(p => p.Field<int>("Converted"));
    // More stuff

I can manually add a filter into the expression directly in the code:

var filteredTotal = table.AsEnumerable().Where(p => p.Field<string>("MyColumn") == "Hello").Sum(p => p.Field<int>("Converted"));

But instead I'd like to pass the "Where" portion as lambda expression instead, but I keep getting lost in the syntax to get the parameters correct.

I have several ways of working around this that don't really involve lambdas but it seems like a nice way of handling this.

Any ideas?

+6  A: 

I'm slightly confused because you're already specifying the Where clause with a lambda expression, but I suspect you want this:

public TrafficTotals CalculateTotals(DataTable table, 
                                     Func<DataRow, bool> filter)
{
    TrafficTotals total = new TrafficTotals();
    total.TotalTraffic = table.AsEnumerable()
                              .Where(filter)
                              .Sum(p => p.Field<int>("Converted"));
    // More stuff
}

You'd then call it with:

totals = CalculateTotals(table, 
                         row => row.Field<string>("MyColumn") == "Hello");

Is that what you're after?

Jon Skeet
The code reads like the first example. The second example is how I wanted it to behave (not how the code was actually written). Dang, I was so close. I wasn't sure what type it wanted for Func but now that I see it, it's pretty dang obvious.
Paul Mrozowski
A: 

If you want to store the lambda expression, you need to declare it like so. This would return true if an integer is less than 3 for example:

Func<int,bool> F = o=>o < 3

Then you can pass it around.

Jason Punyon