Get sum of elements of an Array in C# using generics - c#

I want to write a method which can take an arbitrary array of a numeric type and return the sum of all the elements between startIndex and endIndex. This is what I have:
private static T SumArrayRange<T>(T[] scores, int startIndex, int endIndex)
{
T score = 0;
for (int i = startIndex; i <= endIndex; i++)
{
score += scores[i];
}
return score;
}
But the compilation fails with these 2 errors.
Cannot implicitly convert type 'int'
to 'T'.
Operator '+=' cannot be
applied to operands of type 'T' and
'T'
Is there any way I can force T to be only one of the numeric types (long, double etc.)? Or is their a more elegant way of solving this?

No, there's no way to constrain generic type parameters to use operators, and there are no good workarounds for that, either. A proper one would be an interface such as INumeric or IArithmetic with methods such as Add, Subtract etc, implemented by all primitive types such as int and long. There is a 5-year old feature request for that in MS Connect, which is still Active. The latest word on that is:
Unfortunately, we've had to cut our plans to solve this problem in the .NET Framework 4.0.
Until then, you are relegated to either:
using Reflection yourself - messy and very slow
using any of the existing wrappers that will use Reflection for you (e.g. Microsoft.VisualBasic.CompilerServices.Operators class, with methods such as AddObject, SubtractObject etc which use reflection and implement VB semantics for the corresponding operators) - easy to use, but still very slow
hardcoding types you want to handle (i.e. no support for overloaded arithmetic operators on user-defined types), and using a giant if (x is int) ... else if (x is double) ... statement.

Another approach is to use the LINQ tools that are already available, rather than writing your own. For example:
var mySum = myCollection.Skip(startIndex).Take(count).Sum();
Since the Sum extension method exists for all of the built-in numeric types, you don't have to worry about writing your own. Of course, this won't work if your code's "myCollection" variable is already of a generic collection type.

This approach works pretty well:
http://www.codeproject.com/KB/cs/genericnumerics.aspx

The solution is in dynamic keyword.
T score = default(T)
for (int i = startIndex; i <= endIndex; i++)
{
score += (dynamic)scores[i];
}
return score;
It is a concept named late binding.

There is no type to which you can constrain T that will allow the += operator to work. This is because .NET does not have a type that means numeric.

This is because T could be any type. If T was a HttpWebRequest could you assign 0 to it, or could you use the += operator on it?
You can get around the first error by using
T score = default(T);
I'm not sure how you'd deal with the second because you'd have to constrain T to be types that implement a += operator.

Generic constraints are the only possiblilty I can think of. But, being drunk, I can't exactly test this!

I'm perhaps being stupid, but won't int.Parse() fix this problem?

Here my variant
uses binary operator "add" of type T as default,
but offers ability to customize the add function for some specified types, and use the default binary add only for the rest
(throwing an exception at runtime if binary add isn't defined for type T).
private static Func<T, T, T> CreateAdd<T>()
{
Func<T, T, T> addMethod = null;
Expression<Func<T, T, T>> addExpr = null;
if (typeof(T) == typeof(string))
{
//addExpr = (Expression<Func<T, T, T>>)((a, b) => ((T)(object)((string)(object)a + (string)(object)b)));
//addMethod = addExpr.Compile();
addMethod = (a, b) => {
string aa = (string)(object)a;
string bb = (string)(object)b;
double da;
double db;
double.TryParse(aa, out da);
double.TryParse(bb, out db);
double c = da + db;
string res = c.ToString();
return (T)(object)res;
}; // End Delegate addMethod
}
else
{
ParameterExpression lhs = Expression.Parameter(typeof(T), "lhs");
ParameterExpression rhs = Expression.Parameter(typeof(T), "rhs");
addExpr = Expression<Func<T, T, T>>.Lambda<Func<T, T, T>>(
Expression.Add(lhs, rhs),
new ParameterExpression[] { lhs, rhs }
);
addMethod = addExpr.Compile();
}
return addMethod;
}
// MvcTools.Aggregate.Functions.Sum<T>(vals);
public static T Sum<T>(params T[] vals)
{
T total = default(T);
//Enumerable.Aggregate(vals, delegate(T left, T right) { return left + right; });
Func<T, T, T> addMethod = CreateAdd<T>();
foreach (T val in vals)
{
total = addMethod(total, val);
}
return total;
} // End Function Sum
Example:
int[] vals = new int[] { 1, 2, 3, 4, 5 };
int sum = MvcTools.Aggregate.Functions.Sum<int>(vals);
double[] dvals = new double[] { 1, 2, 3, 4, 5 };
double dsum = MvcTools.Aggregate.Functions.Sum<double>(dvals);
string[] strs = new string[] { "1", "2", "3", "4", "5" };
string str = MvcTools.Aggregate.Functions.Sum<string>(strs);
output: 15, 15.0, "15"

Related

difference Tuple<int, double> vs. (int, double) [duplicate]

I decompiled some C# 7 libraries and saw ValueTuple generics being used. What are ValueTuples and why not Tuple instead?
https://learn.microsoft.com/en-gb/dotnet/api/system.tuple
https://learn.microsoft.com/en-gb/dotnet/api/system.valuetuple
What are ValueTuples and why not Tuple instead?
A ValueTuple is a struct which reflects a tuple, same as the original System.Tuple class.
The main difference between Tuple and ValueTuple are:
System.ValueTuple is a value type (struct), while System.Tuple is a reference type (class). This is meaningful when talking about allocations and GC pressure.
System.ValueTuple isn't only a struct, it's a mutable one, and one has to be careful when using them as such. Think what happens when a class holds a System.ValueTuple as a field.
System.ValueTuple exposes its items via fields instead of properties.
Until C# 7, using tuples wasn't very convenient. Their field names are Item1, Item2, etc, and the language hadn't supplied syntax sugar for them like most other languages do (Python, Scala).
When the .NET language design team decided to incorporate tuples and add syntax sugar to them at the language level an important factor was performance. With ValueTuple being a value type, you can avoid GC pressure when using them because (as an implementation detail) they'll be allocated on the stack.
Additionally, a struct gets automatic (shallow) equality semantics by the runtime, where a class doesn't. Although the design team made sure there will be an even more optimized equality for tuples, hence implemented a custom equality for it.
Here is a paragraph from the design notes of Tuples:
Struct or Class:
As mentioned, I propose to make tuple types structs rather than
classes, so that no allocation penalty is associated with them. They
should be as lightweight as possible.
Arguably, structs can end up being more costly, because assignment
copies a bigger value. So if they are assigned a lot more than they
are created, then structs would be a bad choice.
In their very motivation, though, tuples are ephemeral. You would use
them when the parts are more important than the whole. So the common
pattern would be to construct, return and immediately deconstruct
them. In this situation structs are clearly preferable.
Structs also have a number of other benefits, which will become
obvious in the following.
Examples:
You can easily see that working with System.Tuple becomes ambiguous very quickly. For example, say we have a method which calculates a sum and a count of a List<Int>:
public Tuple<int, int> DoStuff(IEnumerable<int> values)
{
var sum = 0;
var count = 0;
foreach (var value in values) { sum += value; count++; }
return new Tuple(sum, count);
}
On the receiving end, we end up with:
Tuple<int, int> result = DoStuff(Enumerable.Range(0, 10));
// What is Item1 and what is Item2?
// Which one is the sum and which is the count?
Console.WriteLine(result.Item1);
Console.WriteLine(result.Item2);
The way you can deconstruct value tuples into named arguments is the real power of the feature:
public (int sum, int count) DoStuff(IEnumerable<int> values)
{
var res = (sum: 0, count: 0);
foreach (var value in values) { res.sum += value; res.count++; }
return res;
}
And on the receiving end:
var result = DoStuff(Enumerable.Range(0, 10));
Console.WriteLine($"Sum: {result.sum}, Count: {result.count}");
Or:
var (sum, count) = DoStuff(Enumerable.Range(0, 10));
Console.WriteLine($"Sum: {sum}, Count: {count}");
Compiler goodies:
If we look under the cover of our previous example, we can see exactly how the compiler is interpreting ValueTuple when we ask it to deconstruct:
[return: TupleElementNames(new string[] {
"sum",
"count"
})]
public ValueTuple<int, int> DoStuff(IEnumerable<int> values)
{
ValueTuple<int, int> result;
result..ctor(0, 0);
foreach (int current in values)
{
result.Item1 += current;
result.Item2++;
}
return result;
}
public void Foo()
{
ValueTuple<int, int> expr_0E = this.DoStuff(Enumerable.Range(0, 10));
int item = expr_0E.Item1;
int arg_1A_0 = expr_0E.Item2;
}
Internally, the compiled code utilizes Item1 and Item2, but all of this is abstracted away from us since we work with a decomposed tuple. A tuple with named arguments gets annotated with the TupleElementNamesAttribute. If we use a single fresh variable instead of decomposing, we get:
public void Foo()
{
ValueTuple<int, int> valueTuple = this.DoStuff(Enumerable.Range(0, 10));
Console.WriteLine(string.Format("Sum: {0}, Count: {1})", valueTuple.Item1, valueTuple.Item2));
}
Note that the compiler still has to make some magic happen (via the attribute) when we debug our application, as it would be odd to see Item1, Item2.
The difference between Tuple and ValueTuple is that Tuple is a reference type and ValueTuple is a value type. The latter is desirable because changes to the language in C# 7 have tuples being used much more frequently, but allocating a new object on the heap for every tuple is a performance concern, particularly when it's unnecessary.
However, in C# 7, the idea is that you never have to explicitly use either type because of the syntax sugar being added for tuple use. For example, in C# 6, if you wanted to use a tuple to return a value, you would have to do the following:
public Tuple<string, int> GetValues()
{
// ...
return new Tuple(stringVal, intVal);
}
var value = GetValues();
string s = value.Item1;
However, in C# 7, you can use this:
public (string, int) GetValues()
{
// ...
return (stringVal, intVal);
}
var value = GetValues();
string s = value.Item1;
You can even go a step further and give the values names:
public (string S, int I) GetValues()
{
// ...
return (stringVal, intVal);
}
var value = GetValues();
string s = value.S;
... Or deconstruct the tuple entirely:
public (string S, int I) GetValues()
{
// ...
return (stringVal, intVal);
}
var (S, I) = GetValues();
string s = S;
Tuples weren't often used in C# pre-7 because they were cumbersome and verbose, and only really used in cases where building a data class/struct for just a single instance of work would be more trouble than it was worth. But in C# 7, tuples have language-level support now, so using them is much cleaner and more useful.
I looked at the source for both Tuple and ValueTuple. The difference is that Tuple is a class and ValueTuple is a struct that implements IEquatable.
That means that Tuple == Tuple will return false if they are not the same instance, but ValueTuple == ValueTuple will return true if they are of the same type and Equals returns true for each of the values they contain.
In addition to the comments above, one unfortunate gotcha of ValueTuple is that, as a value type, the named arguments get erased when compiled to IL, so they're not available for serialisation at runtime.
i.e. Your sweet named arguments will still end up as "Item1", "Item2", etc. when serialised via e.g. Json.NET.
Other answers forgot to mention important points.Instead of rephrasing, I'm gonna reference the XML documentation from source code:
The ValueTuple types (from arity 0 to 8) comprise the runtime implementation that underlies
tuples in C# and struct tuples in F#.
Aside from created via language syntax, they are most easily created via the
ValueTuple.Create factory methods.
The System.ValueTuple types differ from the System.Tuple types in that:
they are structs rather than classes,
they are mutable rather than readonly, and
their members (such as Item1, Item2, etc) are fields rather than properties.
With introduction of this type and C# 7.0 compiler, you can easily write
(int, string) idAndName = (1, "John");
And return two values from a method:
private (int, string) GetIdAndName()
{
//.....
return (id, name);
}
Contrary to System.Tuple you can update its members (Mutable) because they are public read-write Fields that can be given meaningful names:
(int id, string name) idAndName = (1, "John");
idAndName.name = "New Name";
Late-joining to add a quick clarification on these two factoids:
they are structs rather than classes
they are mutable rather than readonly
One would think that changing value-tuples en-masse would be straightforward:
foreach (var x in listOfValueTuples) { x.Foo = 103; } // wont even compile because x is a value (struct) not a variable
var d = listOfValueTuples[0].Foo;
Someone might try to workaround this like so:
// initially *.Foo = 10 for all items
listOfValueTuples.Select(x => x.Foo = 103);
var d = listOfValueTuples[0].Foo; // 'd' should be 103 right? wrong! it is '10'
The reason for this quirky behavior is that the value-tuples are exactly value-based (structs) and thus the .Select(...) call works on cloned-structs rather than on the originals. To resolve this we must resort to:
// initially *.Foo = 10 for all items
listOfValueTuples = listOfValueTuples
.Select(x => {
x.Foo = 103;
return x;
})
.ToList();
var d = listOfValueTuples[0].Foo; // 'd' is now 103 indeed
Alternatively of course one might try the straightforward approach:
for (var i = 0; i < listOfValueTuples.Length; i++) {
listOfValueTuples[i].Foo = 103; //this works just fine
// another alternative approach:
//
// var x = listOfValueTuples[i];
// x.Foo = 103;
// listOfValueTuples[i] = x; //<-- vital for this alternative approach to work if you omit this changes wont be saved to the original list
}
var d = listOfValueTuples[0].Foo; // 'd' is now 103 indeed
Hope this helps someone struggling to make heads of tails out of list-hosted value-tuples.

Passing multiple arguments into Predicate, Functional Programming

I am trying to better understand functional Programming. The example below was provided, this example creates a predicate lambda. Then creates a static method to Count the number of items that pass the predicate conditions.
public Predicate<string> longWords = (x) => x.Length > 10;
public static int Count<T>(T[] array, Predicate<T> predicate, int counter)
{
for (int i = 0; i < array.Length; i++)
{
if (predicate(array[i]))
{
counter++;
}
}
return counter;
}
I wanted to make this solution follow the Referential Transparency principle which states that you can determine the result of applying that function only by looking at the values of its arguments.
Unfortunately longWords doesn't tell me what a long word really means, I need to pass in an argument to longWords telling it the length that makes a function a long word, ie not hardcoding '10'.
Predicates only take in one parameter, and making longWords require Predicate<Tuple<string,int>>, comes with its challenges.
Below is my attempt at coming to a solution, and the two error messages that resulted.
public class BaseFunctions
{
public Predicate<Tuple<string, int>> longWords = (x) => x.Item1.Length > x.Item2;
public static int Count<T>(T[] array, Predicate<T> predicate, int counter)
{
for (int i = 0; i < array.Length; i++)
{
/// error below: Cannot convert from 'T' to 'string'
/// in the example provided predicate(array[i]) worked fine when the predicate had only string type
if (predicate(new Tuple<string, int>(array[i], 10)))
{
counter++;
}
}
return counter;
}
}
and it's usage
BaseFunctions b = new BaseFunctions();
string[] text = ["This is a really long string", "Not 10"];
/// also error below on BaseFunctions.Count 'The type arguments for method BaseFunctions.Count<T>(T[], Predicate<T>, int) cannot be inferred from the usage. Try specifying the arguments explicitly
Console.WriteLine(BaseFunctions.Count(text, b.longWords, 0).ToString());
Console.ReadLine();
I'd do:
public Func<string, int, bool> longWords = (str, number) => str.Length > number;
instead of:
public Predicate<Tuple<string, int>> longWords = (x) => x.Item1.Length > x.Item2;
This is simply because I believe it's easier to work with a function that takes a string and an int then returns a bool as opposed to a predicate that takes a tuple of string and int and returns a bool. plus this version of the tuple type is cumbersome to work with. consider the new tuple types if you're using C#7 and above.
Then change the method signature from:
public static int Count<T>(T[] array, Predicate<T> predicate, int counter)
to:
public static int Count<T>(T[] array, Func<T, int, bool> predicate, int counter)
To accommodate the change of delegate types mentioned above.
Then the if condition needs to be changed from:
if (predicate(new Tuple<string, int>(array[i], 10)))
to:
if (predicate(array[i], 10))
To accommodate the change of delegate types mentioned above.
Also, note that in C# you'll need to define the array like this:
string[] text = { "This is a really long string", "Not 10" };
and not with the [ ] braces.
Now your usage code becomes:
BaseFunctions b = new BaseFunctions();
string[] text = { "This is a really long string", "Not 10" };
Console.WriteLine(BaseFunctions.Count(text, b.longWords, 0).ToString());
Console.ReadLine();

Generically accessing multidimensional arrays in C#

C# allows creating and populating multidimensional arrays, here is a simple example:
public static void Main(String[] args)
{
var arr = (int[,])CreateArray(new [] {2, 3}, 8);
Console.WriteLine("Value: " + arr[0,0]);
}
// Creates a multidimensional array with the given dimensions, and assigns the
// given x to the first array element
public static Array CreateArray<T>(int[] dimLengths, T x)
{
var arr = Array.CreateInstance(typeof(T), dimLengths);
var indices = new int[dimLengths.Length];
for (var i = 0; i < indices.Length; i++)
indices[i] = 0;
arr.SetValue(x, indices); // Does boxing/unboxing
return arr;
}
This works well. However, for some reason there is no generic version of Array.SetValue(), so the code above does boxing/unboxing, which I'd like to avoid. I was wondering if I missed something or if this is an omission in the .NET API?
No, you are not missing anything: Arrays does not have an option that sets the value without boxing and unboxing.
You do have an alternative to this with LINQ, but it is probably going to be slower than boxing/unboxing for a single element, because compiling a dynamic lambda would "eat up" the potential benefits:
public static Array CreateArray<T>(int[] dimLengths, T x) {
var arr = Array.CreateInstance(typeof(T), dimLengths);
var p = Expression.Parameter(typeof(object), "arr");
var ind = new Expression[dimLengths.Length];
for (var i = 0; i < dimLengths.Length; i++) {
ind[i] = Expression.Constant(0);
}
var v = Expression.Variable(arr.GetType(), "cast");
var block = Expression.Block(
new[] {v}
, new Expression[] {
Expression.Assign(v, Expression.Convert(p, arr.GetType()))
, Expression.Assign(Expression.ArrayAccess(v, ind), Expression.Constant(x))
, Expression.Constant(null, typeof(object))
}
);
Expression.Lambda<Func<object, object>>(block, p).Compile()(arr);
return arr;
}
If you wanted to set all elements in a loop, you could modify the above to compile a dynamically created lambda with multiple nested loops. In this case, you could get an improvement on having to perform multiple boxing and unboxing in a series of nested loops.
for some reason there is no generic version of Array.SetValue()
While it is definitely possible to write a generic method similar to SetValue in the Array class, it may not be desirable. A generic method on a non-generic class would give a false promise of compile-time type safety, which cannot be guaranteed, because the compiler does not know the runtime type of the Array object.
I didn't find any generic ways either to set a value into an Array instance, so I guess the only workaround is to use the unsafe context to avoid boxing.
However, there can be no generic version, now when I think of it. See, when you define a generic method method<T>()..., you do define the parameter for the method: ...<T>(T[] a)... where you have to be specific about the dimensions count, which is one. To create a twodimensional parameter, you define it like this ...<T>(T[,] a)... and so on.
As you can see, by the current syntax of C#, you simple cannot create a generic method, which can accept any-dimensional array.

Passing an IEnumerable of Numeric Values as a parameter to method

I'm playing around with a very simple program to take an array of doubles and return the standard deviation. This part worked but I wanted to make the code more reusable. I would like to make it so the method can accept a parameter of any type that could be considered numeric and return the standard deviation instead of hardcoding a double type (like I initially did in this program). How does one go about this and what is the proper term for it?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication5
{
class Program
{
static void Main(string[] args)
{
double[] avg = { 3.4, 55.6, 10.0, 4.5, 2, 2 };
double x = avg.Average();
//first round of testing
Console.WriteLine("The average of the first array is below ");
Console.WriteLine(x);
Console.WriteLine("below should be the standard deviation!");
Console.WriteLine(CalculateStandardDeviation(avg));
Console.ReadLine();
int[] intAvg = { 4, 3, 5, 6, 2 };
double secondAvg = intAvg.Average();
Console.WriteLine("The average of the second array is below ");
Console.WriteLine(secondAvg);
//this is where the error is happening
//CalculateStandardDeviation(secondAvg);
}
//this is where I tried to make the query more reusable
public static double CalculateStandardDeviation(IEnumerable<double> values)
{
double avg = values.Average();
double sum = 0;
foreach (double d in values)
{
sum += Math.Pow((d - avg), 2);
}
return Math.Pow(sum / (values.Count() - 1),.5);
}
}
}
You could use something like this:
public static decimal CalculateStandardDeviation<T>(IEnumerable<T> values)
{
IEnumerable<decimal> decimalValues = values.Select(v => Convert.ToDecimal(v));
decimal result = 0;
// calculate standard deviation on decimalValues
return result;
}
It will throw an exception if values contains values that can't be converted to a decimal, but will work if the values are of an appropriate type, and I think that makes perfect sense.
Unfortunately, there is no base class for all numbers. You can do this with a generic run-time checking method, or a compile-time safe set of overloads.
Generic Method:
public static T CalculateStandardDeviation(IEnumerable<T> values)
{
var valueArray = values.Select(Convert.ToDecimal).ToArray();
//...
return (T)standardDeviation;
}
The problem with using a single generic method is that you can't put a type constraint on the type parameter that would restrict it to only numeric types. You would have to resort to failing at run-time. There would be nothing to stop you from calling the method with an array of strings, or objects, or Colors, or HttpWebRequests, etc. and unless you do in fact know how to calculate the standard deviation of a color, you should probably stick to individual overrides for a particular numeric type:
I would recommend using the decimal type as your main implementation, and then casting everything to it.
Type-Specific Overloads:
public static decimal CalculateStandardDeviation(IEnumerable<decimal> values)
{
//...
}
public static double CalculateStandardDeviation(IEnumerable<double> values)
{
return (double)CalculateStandardDeviation(values.Select(Convert.ToDecimal));
}
public static int CalculateStandardDeviation(IEnumerable<int> values)
{
return (int)CalculateStandardDeviation(values.Select(Convert.ToDecimal));
}
// etc...
Use C# Generics.
Your function signature will be:
public static T CalculateStandardDeviation(IEnumerable<T> values)
And you can use it like:
int stdDev = CalculateStandardDeviation([int-array]);
double stdDev = CalculateStandardDeviation([double-array]);
Please follow this link:
http://msdn.microsoft.com/en-us/library/ms379564%28VS.80%29.aspx
Edit:
To resolve the Average issue on the generic types, please take a look in this library:
How to Implement Generic Method to do Math calculations on different value types
Obs: Suggestion from Brian.
EDIT
You should use JLRishe's answer, it's much more elegant than this.
You should probably start by adding generics to your method and use the type converter to transform your unknown input into doubles like so :
public static double CalculateStandardDeviation<TSource>(IEnumerable<TSource> inputs)
{
var converter = TypeDescriptor.GetConverter(typeof (double));
if (!converter.CanConvertFrom(typeof(TSource)))
return 0;
var values = new List<double>();
foreach (var value in inputs)
{
values.Add((double) converter.ConvertFrom(value));
}
// Your logic here ...
return ...;
}
I did not tested this snippet but you get the idea.
Foreword:
this answer builds on
How to verify whether a type overloads/supports a certain operator?
and
http://www.codeproject.com/Articles/87438/TinyLisp-A-Language-and-Parser-to-See-LINQ-Express
The second link shows how to compile and evaluate linq expressions.
In short you could forego static type safety and check for the ability of a type to support specific operations at runtime (first link), in case it does not you could throw an exception as the following sample demonstrates:
void Main()
{
DoAdd<float>(5,6);
DoAdd<int>(5,6);
DoAdd<bool>(true,false);
}
// Define other methods and classes here
static void DoAdd<T>(T in1, T in2){
if(!HasAdd<T>()){throw new Exception("Unsupported Type!");}
var c1 = Expression.Constant(in1, typeof(T));
var c2 = Expression.Constant(in2, typeof(T));
var expression=Expression.Add(c1, c2);
Expression<Func<T>> lExpression = Expression.Lambda<Func<T>>(expression);
Func<T> fExpression = lExpression.Compile();
Console.WriteLine(fExpression());
}
static bool HasAdd<T>() {
var c = Expression.Constant(default(T), typeof(T));
try {
Expression.Add(c, c); // Throws an exception if + is not defined
return true;
} catch {
return false;
}
}
Passing an IEnumerable of Numeric Values as a parameter to method will be supported in C# 6.0

How to get the sum of list of shorts using the extension method Sum()?

I was trying to do something like this -
List<short> listofshorts= new List<short>();
int s = listofshorts.Sum();
//this does not work...but same code works for a list of ints..
I got this compilation error -
'System.Collections.Generic.List' does not contain a definition for 'Sum' and the best extension method overload 'System.Linq.Queryable.Sum(System.Linq.IQueryable)' has some invalid arguments
Can anyone suggest how can I use an extension method to calculate the sum of shorts? For some reason the extension method does not support it ...
int s = listofshorts.Sum(d => d);
You can provide the lambda for the method:
List<short> listofshorts= new List<short>();
int s = listofshorts.Sum(a => (int)a);
// This throws an InvalidCastException in .NET 3.5 SP1+
// DO NOT USE THIS CODE
listOfShorts.Cast<int>().Sum();
In the interest of posterity, and pointing out this seemingly obvious solution doesn't work - I'm going to leave this answer with the following links about .NET 3.5 SP1+ behavior:
Puzzling Enumerable.Cast InvalidCastException
http://blogs.msdn.com/b/dinesh.kulkarni/archive/2008/08/10/net-fx-3-5-sp1-two-perf-improvements-linq-to-objects-and-linq-to-sql.aspx
http://blogs.msdn.com/b/ed_maurer/archive/2008/02/16/breaking-change-in-linq-queries-using-explicitly-typed-range-variables.aspx
You could do
int s = listofshorts.Aggregate((i1,i2) => i1+i2);
Like the others have suggested, you will need to cast the short objects to a type which is supported by the Enumerable.Sum method. Unfortunately there are no overloaded Sum method for some of the types like ulong, etc.
If you're gonna be needing it very often though, I'd recommend writing an extension method yourself, here's one I did a while back for ulong and ulong?, you can do something very similar for short or any other types you need:
public static ulong Sum(this IEnumerable<ulong> source)
{
var sum = 0UL;
foreach (var number in source)
{
sum += number;
}
return sum;
}
public static ulong? Sum(this IEnumerable<ulong?> source)
{
var sum = 0UL;
foreach (var nullable in source)
{
if (nullable.HasValue)
{
sum += nullable.GetValueOrDefault();
}
}
return sum;
}
P.S. my implementations are based on the Enumerable.Sum implementation after I took a peek with reflector purely out of curiosity :-P
I would probably chose the .ForEach() extension, you don't need any casting here
short sum = 0;
myListOfShort.ForEach(val => sum += val)

Categories