为什么使用Option Strict On允许Double to Single分配

为什么下面的代码不会导致编译错误,即使我有Option Strict On

Dim value As Single = 12345.12345  ' No error

数字文字默认情况下由编译器解释为Double 。 从Double转换为Single是一个缩小的转换(赋值,在这种情况下,实际上是将值四舍五入到12345.123 )。 根据MSDN文章, Option Strict On具有以下效果:

将隐式数据类型转换限制为仅扩展转换,禁止后期绑定,并禁止导致Object类型的隐式类型转换。

根据该描述,我的示例代码应该会导致错误。 实际上,即使我在文字之后明确指定了字符类型,它仍然不会将其视为错误:

Dim value As Single = 12345.12345R   'Still no error, despite the "R"

即使这不会导致错误:

Dim value As Single = CDbl(12345.12345)   'Still no error, despite the CDbl() conversion

但是,这确实会导致错误,正如我所预料的那样:

Dim value1 As Double = 12345.12345
Dim value2 As Single = value1    ' Causes "Option Strict On disallows implicit conversions from 'Double' to 'Single'" error

同样,如预期的那样,这也失败了:

Public Function GetValue() As Double
    Return 12345.12345
End Function

' ...

Dim value As Single = GetValue()   ' Causes "Option Strict On disallows implicit conversions from 'Double' to 'Single'" error

作为一个方面说明,以下C#中的失败,如预期的那样:

float x = 12345.12345;  ' Causes error in C#

所以,这对所有.NET语言都不是问题。 它似乎是VB.NET的一个特点。

此外,VB.NET不允许这种隐式转换,即使它正在从文字转换:

Dim x As Integer = 1.5  ' Causes error

所以,我的问题是,为什么VB.NET以这种方式工作? 这对我来说似乎是一个缺陷,但也许有一些很好的解释,为什么它允许缩小Double文字到Single转换,但在其他任何情况下都不会。


正如汉斯在上面的评论中指出的那样,VB.NET语言规范在这个话题上非常明确。 在11.2节中,它明确指出:

可以隐式地将IntegerLongIntegerShortByte )的常量表达式转换为更窄的整型,并且Double类型的常量表达式可以隐式转换为Single ,只要常量表达式的值在目的地类型。 无论是使用宽松还是严格的语义,这些缩小的转换都是允许的。

由于这种行为是由规范决定的,所以显然是通过设计。 只要Double值是常量,即使转换导致该值失去精度,也总是允许隐式转换为Single 。 在这种情况下,关于“提供常量表达式的值在目标类型的范围内”有误导性。 Single类型支持表示负无穷大和正无穷大的值,因此当Double值超出Single类型的有效范围时,它将其设置为其中一个无穷大值。

就这一行为的设计决定背后的基本原理而言,我不能肯定地说,但我怀疑这是为了让更方便的语法如下所示:

Dim x As Single = 1 / 2

如果Option Strict On不允许从DoubleSingle的隐式转换,那么您将被迫总是写一些如下所示的简单内容:

Dim x As Single = 1.0F / 2.0F

要么

Dim x As Single = CSng(1 / 2)

在我看来,这可以说是更可取的,但我可以理解为什么语言设计者会认为它的语法太混乱了。

链接地址: http://www.djcxy.com/p/83627.html

上一篇: Why is assignment of Double to Single allowed with Option Strict On

下一篇: Odd Memory Leak in Ionic & Cordova for iOS