为什么从 int 到 uint 的隐式转换有效?

问题描述 投票:0回答:3

使用 Casting null does not compile 作为灵感,来自 Eric Lippert 的评论:

这展示了一个有趣的案例。 “uint x = (int)0;”会 即使 int 不能隐式转换为 uint,也会成功。

我们知道这不起作用,因为

object
无法分配给
string
:

string x = (object)null;

但是确实如此,尽管直观上不应该:

uint x = (int)0;

int 不能隐式转换为

uint
时,为什么
 编译器允许这种情况?

c# .net type-conversion implicit-conversion
3个回答
27
投票

C# 语言将整数常量转换视为非常特殊;这是规范的第 6.1.9 节:

int 类型的常量表达式可以转换为 sbyte、byte、short、ushort、uint 或 ulong 类型,前提是常量表达式的值在目标类型的范围内。 long 类型的常量表达式可以转换为 ulong 类型,前提是常量表达式的值不为负。

这允许您执行以下操作:

byte x = 64;

否则需要丑陋的显式转换:

byte x = (byte)64; // gross

9
投票

以下代码将失败,并显示消息“无法将类型‘int’隐式转换为‘uint’。存在显式转换(是否缺少强制转换?)”

int y = 0;
uint x = (int)y;

这将失败:“常量值'-1'无法转换为'uint'”

uint x = (int)-1;

所以

uint x = (int)0;
起作用的唯一原因是因为编译器认为 0 (或任何其他值 > 0)是一个编译时常量,可以转换为
uint


2
投票

一般来说,编译器有 4 个步骤来转换代码。 文本被标记化 > 标记被解析 > AST 被构建 + 链接 > AST 被转换为目标语言。

对数字和字符串等常量进行求值是第一步,编译器可能会将 0 视为有效标记并忽略强制转换。

© www.soinside.com 2019 - 2024. All rights reserved.