Why is assignment of Double to Single allowed with Option Strict On

Why doesn't the following code cause a compile error, even though I have Option Strict On ?

Dim value As Single = 12345.12345  ' No error

The numeric literal is, by default, interpreted by the compiler as a Double . Converting from Double to Single is a narrowing conversion (the assignment, in this case, actually rounds the value to 12345.123 ). According to the MSDN article, Option Strict On has the following effect:

Restricts implicit data type conversions to only widening conversions, disallows late binding, and disallows implicit typing that results in an Object type.

Based on that description, my example code should cause an error. In fact, even if I explicitly specify the type character after the literal, it still doesn't see it as an error:

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

Even this doesn't cause an error:

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

But, this does cause an error, as I'd expect:

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

Similarly, this also fails, as expected:

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

As a side note, the following fails in C#, as expected:

float x = 12345.12345;  ' Causes error in C#

So, it's not a problem with all .NET languages. It just seems to be a peculiarity of VB.NET.

Also, VB.NET doesn't allow this implicit conversion, even though it is converting from a literal:

Dim x As Integer = 1.5  ' Causes error

So, my question is, why does VB.NET work this way? It seems like a flaw to me, but maybe there is some good explanation as to why it allows narrowing conversions of Double literals to Single , but not in any other situation.


As Hans has pointed out in the comments above, the VB.NET language specification is very clear on this topic. In section 11.2, it clearly states:

Constant expressions of an integral type ( Long , Integer , Short , Byte ) can be implicitly converted to a narrower integral type, and constant expressions of type Double can be implicitly converted to Single , provided the value of the constant expression is within the range of the destination type. These narrowing conversions are allowed regardless of whether permissive or strict semantics are being used.

Since this behavior is dictated by the specification, it is obviously by design. As long as Double value is a constant, the implicit conversion to Single is always allowed, even if the conversion causes the value to lose precision. The bit about "provided the value of the constant expression is within the range of the destination type" is misleading in this case. The Single type supports representing values of negative infinity and positive infinity, so when a Double value is outside of the valid range of the Single type, it just sets it to one of those infinity values.

As far as the rationale behind the design decision for this behavior, I can't say for sure, but I suspect it's to allow for more convenient syntax like this:

Dim x As Single = 1 / 2

If Option Strict On disallowed the implicit conversion from Double to Single , you'd be forced to always write something as simple as that like this:

Dim x As Single = 1.0F / 2.0F

Or

Dim x As Single = CSng(1 / 2)

Which, in my mind, would arguably be preferable, but I can understand why the language designers would decide that the syntax of that would be too confusing.

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

上一篇: 使用PartitionBy按键分割和有效计算RDD组

下一篇: 为什么使用Option Strict On允许Double to Single分配