> ..there's no reason why you couldn’t safely promote a u8, u16, or u32 into a usize, and asking programmers to manually cast integers everywhere makes the code more noisy and verbose.
They have a valid point. In C#, numerical casts that won't lose precision are implicit, and any that could are explicit. I think that’s a nice compromise. So, int to uint requires a cast, but int/uint to long doesn't:
int myInt = /* ... */;
long myLong = myInt;
uint myUInt = myInt; // error CS0266: Cannot implicitly convert type 'int' to 'uint'. An explicit conversion exists (are you missing a cast?)
ulong myULong = myInt; // error CS0266: Cannot implicitly convert type 'int' to 'ulong'. An explicit conversion exists (are you missing a cast?)
uint myUInt = /* ... */;
int myInt = myUInt; // error CS0266: Cannot implicitly convert type 'uint' to 'int'. An explicit conversion exists (are you missing a cast?)
long myLong = myUInt;
ulont myULong = myUInt;