The example Calculate standard deviation in C# makes an extension method that calculates standard deviation for an `IEnumerable` of integers.

Unfortunately because that example works with integers, it cannot work with other data types. Rian Meier showed me this method, which uses generics to work with other data types.

The new method applies to the generic type `IEnumerable<T>`. Ideally it would be nice to restrict the generic type `T` to numeric types, but C# doesn’t have a syntax for that.

Rian’s solution was to use the following code to test the elements in the `IEnumerable` to see if they can be converted into doubles.

`double testDouble;
bool isNumeric = values.All(
value => double.TryParse(value.ToString(), out testDouble));
if (!isNumeric)
return double.NaN;`

That works but I prefer to throw an exception instead of returning `NaN`. That way a programmer cannot accidentally think the returned result is a standard deviation. If there is a problem, it will be immediately obvious so the programmer can fix it.

The following code shows the new extension method.

`// Return the standard deviation of an array of Doubles.
//
// If the second argument is True, evaluate as a sample.
// If the second argument is False, evaluate as a population.
public static double StdDev<T>(this IEnumerable<T> values,
bool as_sample)
{
// Convert into an enumerable of doubles.
IEnumerable<double> doubles =
values.Select(value => Convert.ToDouble(value));
// Get the mean.
double mean = doubles.Sum() / doubles.Count();
// Get the sum of the squares of the differences
// between the values and the mean.
var squares_query =
from double value in doubles
select (value - mean) * (value - mean);
double sum_of_squares = squares_query.Sum();
if (as_sample)
{
return Math.Sqrt(sum_of_squares / (doubles.Count() - 1));
}
else
{
return Math.Sqrt(sum_of_squares / doubles.Count());
}
}`

The code first calls the original `IEnumerable` list’s `Select` method to “project” the original items into doubles and saves the result in a new `IComparable<double>`. If the items in the `IEnumerable` cannot be converted into doubles, this statement fails and throws an exception.

After this the method works exactly as before. See the previous example for information about calculating the standard deviation.

##
About RodStephens

Rod Stephens is a software consultant and author who has written more than 30 books and 250 magazine articles covering C#, Visual Basic, Visual Basic for Applications, Delphi, and Java.

When you say “uses generics to work with other data types” are you saying works with decimal numbers and negative numbers? I made something similar in vb6 to track student performances in tests using integers and plotting student names and scores. I see you example illustrates modal values for the scores gained. Nice!

Generics let a method or class work with an unknown data type. In this example, they let

StdDevmethod work with any numeric type including float, double, int, long, etc. The example needs to do some work to ensure that it doesn’t try to work with non-numeric types such as controls, timers,Employeeobjects, etc.