C# 有符号和无符号整数是双向缩小转换吗?

C# signed and unsigned integers are Narrowing conversion both ways?

根据 MSDN 文章:https://msdn.microsoft.com/en-us/library/8s682k58%28v=vs.80%29.aspx

Explicit conversion is required by some compilers to support narrowing conversions..

根据上述 msdn link 中的陈述,可以安全地说

将 int 转换为 uint 是缩小转换

此外,

将 uint 转换为 int 是缩小转换范围

?

将整数或浮点类型从有符号转换为无符号,反之亦然既不是缩小转换也不是扩大转换,因为用于存储它的位数保持不变。

相反,它是一种表示形式的变化,可以完全改变数字(例如,有符号 -1 转换为无符号 0xffffffff)。

事实上,如果你使用未经检查的算法:

unchecked
{
    int  x = -1;
    uint y = (uint) x;
    int  z = (int) y;

    Debug.Assert(x == z); // Will succeed for all x.

    uint a = 0xffffffff;
    int  b = (int) a;
    uint c = (uint) b;

    Debug.Assert(a == c); // Will succeed for all a.
}

所以往返两个方向都有效,这证明两个方向都不会发生变窄。

缩小和扩大仅适用于使用不同位数存储数字的一个或多个部分的整数和浮点类型。

但是,因为数字的值是可以改变的,所以你必须强制转换才能进行这样的转换,以确保你不会不小心。

不是缩小,但还是要显式。两者都可以拥有对方所没有的价值。 int 可以保存负值,uint 不能,uint 可以保存大于 2147483647 的值,这是 int.

的最大值

但是,intuint 都使用 32 位(= 4 字节)来保存信息。
当您将 int 转换为 byte 时,您将丢失信息,因为 byte 只能容纳 8 位。
intuint 之间的转换不会丢失任何位,但这些位具有不同的含义。 (在 50% 的情况下)
您必须对此明确说明,以表明您知道自己在做什么。它将防止由隐式转换引起的错误。