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