VB.NET ".?" Syntax OR GreaterThan Breaking Change
See original GitHub issueVersion Used: Somewhere between the version in msbuild 16.1 and 16.7
Steps to Reproduce:
Code example:
Sub Main()
Dim map As Map = Nothing
Console.WriteLine($"1 (Expect Empty): {IsHit(map, 0, 0)}")
map = New Map() With {.Positions = Nothing}
Console.WriteLine($"2 (Expect Empty): {IsHit(map, 0, 0)}")
map = New Map() With {.Positions = New List(Of List(Of String))()}
map.Positions.Add(Nothing)
Console.WriteLine($"3 (Expect Empty): {IsHit(map, 0, 0)}")
map = New Map() With {.Positions = New List(Of List(Of String))()}
map.Positions.Add(New List(Of String)())
map.Positions(0).Add(Nothing)
Console.WriteLine($"4 (Expect Empty): {IsHit(map, 0, 0)}")
map = New Map() With {.Positions = New List(Of List(Of String))()}
map.Positions.Add(New List(Of String)())
map.Positions(0).Add("")
Console.WriteLine($"5 (Expect Miss): {IsHit(map, 0, 0)}")
map = New Map() With {.Positions = New List(Of List(Of String))()}
map.Positions.Add(New List(Of String)())
map.Positions(0).Add("X")
Console.WriteLine($"6 (Expect Hit): {IsHit(map, 0, 0)}")
Console.ReadLine()
End Sub
Function IsHit(map As Map, x As Integer, y As Integer) As String
Try
If map?.Positions?.Count() > x AndAlso map.Positions(x)?.Count() > y AndAlso Not map.Positions(x)(y) Is Nothing Then
If map.Positions(x)(y).Equals("X", StringComparison.InvariantCultureIgnoreCase) Then
Return "Hit"
Else
Return "Miss"
End If
Else
Return "Empty"
End If
Catch ex As Exception
Return $"Error - {ex.Message}"
End Try
End Function
Class Map
Public Property Positions As List(Of List(Of String))
End Class
Expected Behavior:
Output:
1 (Expect Empty): Empty
2 (Expect Empty): Empty
3 (Expect Empty): Empty
4 (Expect Empty): Empty
5 (Expect Miss): Miss
6 (Expect Hit): Hit
Actual Behavior:
Output:
1 (Expect Empty): Error - Object reference not set to an instance of an object.
2 (Expect Empty): Error - Object reference not set to an instance of an object.
3 (Expect Empty): Error - Object reference not set to an instance of an object.
4 (Expect Empty): Empty
5 (Expect Miss): Miss
6 (Expect Hit): Hit
When running code compiled using an older version of the compiler, the map?.Positions?.Count() > x AndAlso map.Positions(x)?.Count() > y AndAlso Not map.Positions(x)(y) Is Nothing
If check will return False
and the output is as expected. However, on newer versions, this same if will throw a null reference exception.
Issue Analytics
- State:
- Created 3 years ago
- Comments:26 (14 by maintainers)
Top Results From Across the Web
Visual Basic breaking changes in .NET Core 3.0
The following is a list of breaking changes in Visual Basic: Types in Microsoft.VisualBasic.ApplicationServices namespace not available ...
Read more >How to: Break and Combine Statements in Code - Visual ...
In the following example, the statement is broken into four lines with line-continuation characters terminating all but the last line. Using ...
Read more >vb.net Add Watch stop when value changes
You can right click on a break point and then choose Condition. In the condition box type the name of the variable and...
Read more >An Exhausting List of Differences Between VB.NET & C# | ...
This is NOT a list of syntax differences between VB and C# (of which there are countless). I'll mostly be talking about semantic...
Read more >Visual Basic (VB.NET) – Full Course for Beginners - YouTube
Lean the fundamentals of programming with Visual Basic (sometimes called ... how to write code to validate and process the data collected.
Read more >
Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free
Top Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Sorry missed this issue. The change which caused this difference is #38802.
The core issue here is that the result of
AndAlso
in VB when dealing with nullable values is not justTrue
andFalse
but can also contain the resultNothing
. Specifically it means thatCType(Nothing, Nullable(Of Boolean) AndAlso False
produces the valueFalse
. That means that in the case of nullable operations VB is not short circuiting when the left hand side returnsNothing
. It must evaluate the right hand side to understand the return.This has been the design of VB since nullable values were introduced. Unfortunately an optimization bug slipped into the compiler which caused this logic to not be consistently applied to user code. As a result it was hard for customers to predict how their programs would work and hard for us to maintain the broken logic here. After several attempts to maintain the logic we decided it was better to fix the optimization bug.
This does mean that
AndAlso
is not necessarily short circuiting when nullable values are involved (that has been true though since nullable was added). The code in this case needs to guard againstmap
beingNothing
in all of the branches ofAndAlso
.Sharp lab demo of the behavior
Will need investigation on the VB side about this. At first glance it seems wrong.