The method syntax is blocking implicit conversions, but the query syntax is not. Option Strict
is on. How can I force errors to appear when using the query syntax?
Whole (Completely Runnable) Program:
Option Strict On
Module Module1
Sub Main()
Dim custList As New List(Of Cust)()
custList.Add(New Cust() With {.Name = "Mr. Current", .Deleted = False})
custList.Add(New Cust() With {.Name = "Mrs. Deleted", .Deleted = True})
custList.Add(New Cust() With {.Name = "Miss Null", .Deleted = Nothing})
Dim QuerySyntax =
From c In custList
Where c.Deleted = False 'no error (the problem)
Dim MethodSyntax =
custList _
.Where(Function(c) c.Deleted = False) 'compiler error (desired effect)
For Each c As Cust In QuerySyntax
Console.WriteLine("Q: " & c.Name & " " & c.Deleted)
Next
For Each c As Cust In MethodSyntax
Console.WriteLine("M: " & c.Name & " " & c.Deleted)
Next
Console.ReadKey(True)
End Sub
Class Cust
Public Property Name() As String
Public Property Deleted() As System.Nullable(Of Boolean)
End Class
End Module
Lines that are the crux of the question:
Where c.Deleted = False 'no error
.Where(Function(c) c.Deleted = False) 'compiler error
I'm going to go out at least a bit of a limb and offer that I've found an explanation for this behavior.
I took this code and changed
'c.Deleted = Nothing'
in theQuerySyntax
version and immediately got a "green squiggly" saying "This expression will always evaluate to Nothing due to null propagation of the equals operator.
" That led me to think about how the compiler is interpreting the expression, and so I did a bit more snooping, and found the following:VB.Net Linq to Entities Null Comparison - 'Is Nothing' or '= Nothing'?
From that post, it appears that when a
Nullable(Of T)
is involved in the expression, the compiler is internally promoting (or, I suppose, more accurately, "lifting") the equality operator toNullable(Of T)
version, which I suppose is not, technically, an "implicit conversion." As a result, it doesn't generate the compile-time error. Because the element is passed as aparameter
to the function in theMethodSyntax
version, the lifting operator isn't being applied, and the compiler then traps the implicit conversion syntax.