gpt4 book ai didi

c# - 当没有这样的运算符时显式转换为 uint

转载 作者:行者123 更新时间:2023-11-30 13:15:23 26 4
gpt4 key购买 nike

我已经用私有(private)数据成员围绕 ulong 编写了一个简单的包装器。我希望能够将包装器转换为 ulong 以检索数据。我希望强制转换为 uint 并丢失数据是非法的,因此我没有编写对 uint 的显式转换。当 C# 允许我毫无怨言地转换为 uint 并且即使高位丢失也没有抛出异常时,您可以想象我的惊讶。

这是我的测试代码:

class Program {
static void Main(string[] args) {
ULongWrapper a = new ULongWrapper(0xfffffffffUL);
ulong b = (ulong)a;
uint c = (uint)a;
Console.WriteLine("{0:x}", b);
Console.WriteLine("{0:x}", c);
}
}
class ULongWrapper {
private ulong data;
public ULongWrapper(ulong data) {
this.data = data;
}
public static explicit operator ulong(ULongWrapper x) {
return x.data;
}
}

打印:

fffffffff
ffffffff

这似乎是不受欢迎的行为,因为我希望对 uint 的转换在编译时失败!编译器使用 ulong 显式转换运算符,然后以某种方式将该结果隐式转换为 uint,而不进行边界检查。这是 C# 中的错误吗?如果不是,为什么?

最佳答案

Is this a bug in C#?

没有。

Why not?

因为这里演示的行为是符合规范的。仔细阅读规范的第 6.4.4 和 6.4.5 节。 (请注意,C# 编译器在许多方面与规范的这一部分不一致;实现在模糊的极端情况下存在许多错误,特别是涉及提升运算符。)

I want it to be illegal to cast to uint and lose data.

不幸的是,你不能总是得到你想要的。

You can imagine my surprise when C# allowed me to cast to uint without complaint and did not throw an exception even though the high bits were lost.

这有点令人惊讶,我同意。

规则是:每个用户定义的转换都允许在输入输出 上插入一个标准转换。此外,如果它是一个显式转换——也就是说,您正在进行强制转换——那么插入的标准转换可能是隐式或显式标准转换。 (事实上​​,强制转换可能导致将显式标准转换插入到用户定义的隐式转换中!)

在您的情况下,存在从 ULongWrapper 到 ulong 的显式用户定义转换,以及从 ulong 到 uint 的标准显式转换。因此,将 ULongWrapper 转换为 uint 是合法的。

您可能首先考虑不实现显式转换,因为显然您不喜欢显式转换的语义。只需编写一个返回底层 ulong 的方法或属性,然后就可以完成了。

关于c# - 当没有这样的运算符时显式转换为 uint,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9575826/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com