方法语法是阻止隐式转换,但查询语法不是。 Option Strict
已开启。 如何在使用查询语法时强制显示错误?
整个(完全可运行)程序:
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
问题的关键点:
Where c.Deleted = False 'no error
.Where(Function(c) c.Deleted = False) 'compiler error
答案 0 :(得分:2)
我要出去至少有点肢体并且提出我已经找到了解释这种行为的原因。
我在'c.Deleted = Nothing'
版本中使用了此代码并更改了QuerySyntax
,并立即得到了一个"绿色波浪形"说" This expression will always evaluate to Nothing due to null propagation of the equals operator.
"这让我想到了编译器如何解释表达式,所以我做了更多的窥探,并发现了以下内容:
VB.Net Linq to Entities Null Comparison - 'Is Nothing' or '= Nothing'?
从该帖子看来,当表达式中涉及Nullable(Of T)
时,编译器在内部宣传(或者,我想,更准确地说,"提升&# 34;)等于Nullable(Of T)
版本的运算符,我认为这在技术上并不是一种隐式转换。"因此,它不会产生编译时错误。由于该元素作为parameter
传递给MethodSyntax
版本中的函数,因此不会应用提升运算符,然后编译器会捕获隐式转换语法。
答案 1 :(得分:2)
感谢@David W的评论,他们帮我指了解答案!
方法语法:
.Where
方法特别是System.Linq.Enumerable.Where
方法,它指定谓词参数是一个返回Boolean
值的labmba函数。当@GSerg发布时,比较将返回Boolean?
值,因此编译器会抛出错误。
查询语法
相反,查询语法的Where
子句接受"表达式"作为条件参数。
关于这个条件参数,MSDN继续说:
Where子句中使用的表达式必须求值为a 布尔值或等效的布尔值,例如整数 当值为零时,求值为False。
<强>结论强>
换句话说,使用查询语法,将始终计算表达式。因此,Option Strict
将无效,因为编译器正在考虑计算表达式的结果而不考虑表达式本身的数据类型。