ulong Test2 = UInt32.MaxValue * UInt32.MaxValue
Can be translated into:
UInt32 __temp = UInt32.MaxValue * UInt32.MaxValue;
since the operation to the left of the = sign is always performed without any type conclusions on the right, obviously not what you want ...
It should be
ulong Test2 = (long)UInt32.MaxValue * UInt32.MaxValue;
This will be considered as:
ulong Test2 = (long)UInt32.MaxValue * (long)UInt32.MaxValue;
And it will work.
The rules are given in section 16.4.2 of the C # norm:
Numeric promotion consists of automatically performing certain implicit conversions of operands of predefined unary and binary numeric operators. Numerical promotion is not a separate mechanism, but rather the effect of permission overloading on predefined operators. Numeric promotion is not specifically affected by the evaluation of user agents, although user agents may have similar effects introduced.
As an example of digital advertising, consider the predefined implementations of the binary * operator:
int operator *(int x, int y); uint operator *(uint x, uint y); long operator *(long x, long y); ulong operator *(ulong x, ulong y); void operator *(long x, ulong y); void operator *(ulong x, long y); float operator *(float x, float y); double operator *(double x, double y); decimal operator *(decimal x, decimal y);
When overload resolution rules (ยง14.4.2) are applied to this set of statements, the first of the statements should be selected for which implicit conversions exist from operand types. [Example: for operation b * s, where b is byte and s is short, overload resolution selects the * (int, int) operator as the best operator. Thus, the effect is that b and s are converted to int and the result type is int. Similarly, for operation I * d, where I am int and d is double, overload resolution selects the * (double, double) operator as the best operator. end of example]