Consider this static test class:
public static class Test
{
public static ushort sum(ushort value1, ushort value2)
{
return value1 + value2
}
}
This causes the following compile error, with value1 + value2
underlined in red:
Cannot implicitly convert type 'int'
to 'ushort'. An explicit conversion
exists (are you missing a cast)?
Why?
Like C and C++ before it, integers are implicitly widened when used with many operators. In this case, the result of adding two ushort
values together is int
.
Update:
More information: http://msdn.microsoft.com/en-us/library/aa691330(v=VS.71).aspx
I believe this was originally added in C/C++ because int
was a native integer type (and yes, operations were faster on int
s than on short
s on 32-bit architectures). I'm unsure of the full rationale for C#.
It does make you think about overflow/truncation considerations when you cast. Accidental overflow is more likely with the smaller integer types.
ushort
The following assignment statement
will produce a compilation error,
because the arithmetic expression on
the right-hand side of the assignment
operator evaluates to int by default.
ushort z = x + y; // Error: conversion from int to ushort
To fix this problem, use a cast:
ushort z = (ushort)(x + y); // OK: explicit conversion
The available addition operators in C# only contemplate int
, uint
, long
and ulong
data types so in that case you are implicitly casting two ushort
instances to int
, then performing the addition and then returning an int
that cannot be implicitly cast to ushort
.
From the C# 4.0 specification, section 7.8.4 Addition operator, you can check that only the the following integer addition operators are available:
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 same section also states:
The operands are converted to the
parameter types of the selected
operator, and the type of the result
is the return type of the operator.
Which explains why that expression results in an int
.
It is because addition or subtraction of ushorts doesn't necessarily result in a ushort. For example, the result could be < 0, which is not a ushort. So you need to give the compiler the hint to not complain by type casting it. I believe this should work: return (ushort)(value1 + value2);