在下面的示例代码中,我将除以0,当我使用调试器单步执行时,(被除数/除数)会产生一个无穷大或NaN (如果除数是零)。当我将这个结果转换为长整型时,我得到一个有效的结果,通常类似于-9223372036854775808。为什么这个强制转换是有效的?为什么它不停止执行(例如抛出异常),而是分配一个任意值?
double divisor = 0;
double dividend = 7;
long result = (long)(dividend / divisor);发布于 2010-04-15 02:42:38
为什么此强制转换有效?
如果在编译时知道转换可能成功或总是成功,则强制转换是有效的。仅当转换不可能成功时,强制转换才是非法的。(例如,将密封类型强制转换为它未实现的接口。)从double到long的转换可能会成功。因此,强制转换是有效的。
为什么它不停止执行(例如抛出异常),而是分配一个任意值?
因为你没有要求例外!该规范非常清楚地说明了预期行为是什么。参见第6.2.1节:
对于从浮点型或双精度型到整型类型的转换,处理过程取决于发生转换的溢出检查上下文:
在选中的上下文中,转换过程如下所示:
·如果操作数的值为NaN或infinite,则抛出System.OverflowException。
..。
在未检查的上下文中,转换始终成功,并按如下方式进行。
·如果操作数的值为NaN或infinite,则转换结果为目标类型的未指定值。
您在未检查的上下文中执行代码;您没有要求任何异常,所以没有得到任何异常。如果你想要一个例外,那就请求一个;使用一个检查过的上下文。
发布于 2010-04-15 02:14:24
默认情况下,未选中C#算术,因此无效操作不会抛出异常。
您可以使用checked block强制运行时检查溢出并引发异常,如下所示:
checked {
double divisor = 0;
double dividend = 7;
long result = (long)(dividend / divisor);
}请注意,这将会有轻微的性能损失。
发布于 2010-04-15 02:48:35
在C#语言规范的第6.2.1节中明确记录了该行为:
对于从浮点型或双精度型到整型类型的转换,处理过程取决于发生转换的溢出检查上下文(§7.5.12):
在选中的上下文中,转换过程如下所示:
在未检查的上下文中,转换始终成功,并按如下方式进行。
如果操作数的值为NaN或infinite,则转换结果为目标type.
添加粗体是为了强调。你已经有了无限和一个未检查的上下文。您得到的值是未指定的。使用checked关键字使其成为炸弹。
https://stackoverflow.com/questions/2639860
复制相似问题