提问人:Dave Cousineau 提问时间:7/17/2023 更新时间:7/17/2023 访问量:84
为什么在强制转换运算符中将 double 隐式转换为 int?
Why is double implicitly converted to int in a cast operator?
问:
这是我以前没有注意到的奇怪行为。我预计无法从 a 强制转换,但该值被隐式转换为 an,我默默地丢失了小数部分。我真的不能在不从 s 转换的情况下从 s 转换吗?double
double
int
int
double
readonly struct TestDecimal {
public decimal Value { get; }
TestDecimal(decimal value) =>
Value = value;
public static explicit operator TestDecimal(int x) => new(x);
}
...
// these assertions fail, but really this shouldn't even compile
[TestMethod]
public void Test_CastFromDouble() {
var value = (TestDecimal)12.34; // shouldn't compile
Assert.AreEqual(12.34m, value.Value); // assertion failed, actual value: 12.0m
}
[TestMethod]
public void Test_CastFromDecimal() {
var value = (TestDecimal)12.34m; // shouldn't compile
Assert.AreEqual(12.34m, value.Value); // assertion failed, actual value: 12.0m
}
答:
2赞
Sweeper
7/17/2023
#1
这是因为标准转换可以作为用户定义转换的一部分进行。在用户定义的转换之前,可以进行标准转换,将表达式的类型转换为转换运算符所需的类型。还可以进行另一种标准转换,将转换运算符的返回值转换为该上下文中预期的任何类型。
一旦最具体的用户定义转换运算符 识别后,实际执行用户自定义转换 最多涉及三个步骤:
- 首先,如果需要,执行从源表达式到用户定义或提升的操作数类型的标准转换 转换运算符。
- 接下来,调用用户定义或提升的转换运算符来执行转换。
- 最后,如果需要,执行从用户定义的转换运算符的结果类型到目标的标准转换 类型。
然后,本节继续定义诸如最包含类型的术语,然后在 §10.5.5 中使用这些术语来描述如何准确解决这些转换。
对于您的案例来说,最重要的是,标准的显式转换包括“ to ”和“ to ”。这使您能够使用 / 作为参数调用转换运算符。请参阅语言规范部分:double
int
decimal
int
double
decimal
标准显式转换都是标准隐式转换 转化次数加上显式转化的子集,其中 存在相反的标准隐式转换。
“到”和“到”都是“存在相反标准隐式转换的显式转换”。double
int
decimal
int
- ...
- 从 到 、 、 、
double
sbyte
byte
short
ushort
int
uint
long
ulong
char
float
double
- 从 到 、 、 、
decimal
sbyte
byte
short
ushort
int
uint
long
ulong
char
float
double
- ...
以下隐式转换被归类为标准隐式转换 转换:
- ...
- 隐式数字转换 (§10.2.3)
隐式数值转换包括:
- ...
- 从 到 、 、 或 。
int
long
float
double
decimal
- ...
评论
0赞
Dai
7/17/2023
链接的文章描述的是 - 和 - 但不是 。double
int
int
decimal
decimal
int
0赞
Sweeper
7/17/2023
@Dai 对不起,我忘记了问题中的第二个例子,引号有点不完整。现在应该修复它。
0赞
Dave Cousineau
7/17/2023
我怀疑是这样的,但可以使用显式转换似乎是错误的。
评论
ldc.i4.s 12
ldc.i4.s
lcd.i4.s
int8
u8
byte
12
12
int8