Why is my addition of 2 shorts causing a casting compile error due to ints?
In my code i have the following code:
Order = config.DeploymentSteps.Select(x => x.Order).DefaultIfEmpty().Max() + 1;
This gives me the error开发者_Go百科 Cannot implicitly convert type 'int' to 'short'
. As a Reference Order
and x.Order
are both shorts, and Max()
is correctly returning a short
(I have verified this). So I get it, it thinks the 1
is an integer
and erroring. So I changed it to:
Order = config.DeploymentSteps.Select(x => x.Order).DefaultIfEmpty().Max() + (short)1;
I'm now still getting the same compile. So maybe it's not casting it right, so I tried changing it to
Order = config.DeploymentSteps.Select(x => x.Order).DefaultIfEmpty().Max() + Convert.ToInt16(1);
Yet I still get the same error. Finally I got it to work by converting the whole expression:
Order = Convert.ToInt16(config.DeploymentSteps.Select(x => x.Order).DefaultIfEmpty().Max() + 1);
Why can't I cast the 1 to a short
and add it to another short, without casting the whole thing?
It is because short + short = int.
Eric Lippert explains it here.
He says:
Why is short plus short result in int?
Well, suppose short plus short was short and see what happens:
short[] prices = { 10000, 15000, 11000 }; short average = (prices[0] + prices[1] + prices[2]) / 3; And the average is, of course, -9845 if this calculation is done in shorts. The sum is larger than the largest possible short, so it wraps around to negative, and then you divide the negative number.
In a world where integer arithmetic wraps around it is much more sensible to do all the calculations in int, a type which is likely to have enough range for typical calculations to not overflow.
As much as it sounds redundant, would you mind declaring a short variable (or perhaps a const) and initilize it to 1 and use that while assigning your Order variable. Unlike an int or long, there is no literal way of specifying a short.
The C# language specification (download link) lists the predefined addition operators. For integral types, these are:
int operator +(int x, int y);
uint operator +(uint x, uint y);
long operator +(long x, long y);
ulong operator +(ulong x, ulong y);
The reason you have to cast is because there's no specific operator to add shorts. I know that "because C# is made to work like this" isn't a particularly useful answer but there you go. I'd just go with:
Order = (short) config.DeploymentSteps.Select(x => x.Order).DefaultIfEmpty().Max() + 1;
or:
Order = config.DeploymentSteps.Select(x => x.Order).DefaultIfEmpty().Max();
Order++;
精彩评论