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 theQuerySyntaxversion 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 aparameterto the function in theMethodSyntaxversion, the lifting operator isn't being applied, and the compiler then traps the implicit conversion syntax.