The short answer is "because the Standard says that it shall be so", which see the informative §14.2.5.2 of ISO 23270. The normative §13.1.2. (Implicit numeric conversions) says:
The implicit numeric conversions are:
...
- From
int
to long
, float
, double
, or decimal
.
- From
uint
to long
, ulong
, float
, double
, or decimal
.
...
Conversions from int
, uint
, long
or ulong
to float
and from long
or ulong
to double
can cause a loss of precision, but will never cause a loss of magnitude.
The other implicit numeric conversions never lose any information. (emph. mine)
The [slightly] longer answer is that you are adding two different types: a 32-bit signed integer and a 32-bit unsigned integer:
- the domain of a signed 32-bit integer is -2,147,483,648 (0x80000000) — +2,147,483,647 (0x7FFFFFFF).
- the domain of an unsigned 32-bit integer is 0 (0x00000000) — +4,294,967,295 (0xFFFFFFFF).
So the types aren't compatable, since an int
can't contain any arbitrary uint
and a uint
can't contain any arbitrary int
. They are implicitly converted (a widening conversion, per the requirement of §13.1.2 that no information be lost) to the next largest type that can contain both: a long
in this case, a signed 64-bit integer, which has the domain -9,223,372,036,854,775,808 (0x8000000000000000) — +9,223,372,036,854,775,807 (0x7FFFFFFFFFFFFFFF).
Edited to note: Just as an aside, Executing this code:
var x = 1024 + 2048u ;
Console.WriteLine( "'x' is an instance of `{0}`" , x.GetType().FullName ) ;
does not yield a long
as the original poster's example. Instead, what is produced is:
'x' is an instance of `System.UInt32`
This is because of constant folding. The first element in the expression, 1024
has no suffix and as such is an int
and the second element in the expression 2048u
is a uint
, according to the rules:
- If the literal has no suffix, it has the first of these types in which its value
can be represented:
int
, uint
, long
, ulong
.
- If the literal is suffixed by
U
or u
, it has the first of these types in which its value can be represented: uint
, ulong
.
And since the optimizer knows what the values are, the sum is precomputed and evaluated as a uint
.
Consistency is the hobgoblin of little minds.