开发者

LINQ aggregate functions on bytes, shorts, and unsigned values

开发者 https://www.devze.com 2023-03-12 09:07 出处:网络
How would you go about using LINQ aggregate functions (ex. Sum, Average) on collections of bytes, shorts, and unsigned values?Granted, I\'m a new C# programmer, but I can\'t even figure out how to get

How would you go about using LINQ aggregate functions (ex. Sum, Average) on collections of bytes, shorts, and unsigned values? Granted, I'm a new C# programmer, but I can't even figure out how to get something that compiles let alone has proper output.

H开发者_开发百科ere's a trivial example of what I am trying to do:

short[] numbersArray = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };
short sumArray = numbersArray.Sum();

or

List<short> numbersList = new List<short> { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };
short sumList = numbersList.Sum();

I can't either of these samples to work. If I change the data type to int it works, but I can't get it to work for shorts, bytes, uints, etc.

What am I doing wrong?


Enumerable.Sum<T>() is only defined for IEnumerable<T> where T in

double,
double?
int,
int?
decimal,
decimal?
long,
long?
float,
float?

This is because there is no addition operator* for short or any of the other primitive types (short + short is int, for example).

You have to say:

short[] numbersArray = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };
int sumArray = numbersArray.Sum(x => (int)x);

and less explicitly you can get away with

short[] numbersArray = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };
int sumArray = numbersArray.Sum(x => x);

In this case, you are now invoking the overload:

int Enumerable.Sum<short>(
    this IEnumerable<short> source,
    Func<short, int> selector
)

*: Here I mean "operator" in the sense of an function F:(short x short) -> short.


Enumerable.Sum accepts either ints, longs, singles or doubles.

You can cast the numbers to make them eligible as the parameter:

short [] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };
int sum = numbers.Cast<int> ().Sum ();

As an alternative, you can provide a Func<TSource, int> lambda that selects ints for you:

short [] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };
int sum = numbers.Sum (x => x); // lambda type is inferred as Func<short, int>

I declare sum as int because it's really unsafe to think a sum of shorts is a short itself.
It is even reflected in the fact that you have to do explicit casting when adding shorts:

int sum = a + b; 
short shortSum = (short)(a + b); // you can use an explicit casting to get short

So if you're certain you're not going to overflow, just cast the result:

short shortSum = (short) numbers.Cast<int> ().Sum ();


The Sum extension method doesn't have an overload that takes an IEnumerable<short>.

Instead, you can pass a lambda expression that implicitly converts the shorts to ints:

short sumList = (short)numbersList.Sum(i=>i);


This confused me, but I was able to make it work like:

List<short> li = new List<short> {1,2,3,4,5};
short l = (short)li.Sum(i => i);
0

精彩评论

暂无评论...
验证码 换一张
取 消