I've written JavaScript for a while, but lately I've been writing a lot of C#. I wanted to write a method that could take the column name of a DataTable
and return an average for those values. Having never written closures in C#, but being comfortable with them in JavaScript, I came up with this:
public static double GetColumnAverage(DataTable dt,string columnName)
{
Func<DataTable, double> getAverage = (t) => t.AsEnumerable().Where(x => x[columnName] != DBNull.Value)
.Average(x => x.Field<dynamic>(columnName));
bool isNumeric = true;
foreach (DataRow row in dt.Rows)
{
var type = row[columnName].GetType();
//not all numeric data types, but close enough for this
isNumeric = type == typeof(int) || type == typeof(double) || type == typeof(float) || type == typeof(uint)
|| type == typeof(byte);
if (isNumeric ==false)
{
throw new Exception();
}
}
return getAverage(dt);
}
From this I learned that the parameters passed to an inner delegate are matched to the outer delegate, so Intellisense picked up the t
parameter as a DataTable (not sure about implications, but neat). Cool. My initial thought was to create a private helper method IsNumeric
that would return a bool if the value in the DataRow was something we could average.
I know that I could probably improve this a little, but I'm wondering if there's any practical reason to using a closure here, or if there are any potential pitfalls that might make it a bad idea?