2

方法语法会阻止隐式转换,但查询语法不会。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
4

2 回答 2

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 比较 - “什么都没有”或“= 什么都没有”?

从那篇帖子看来,当Nullable(Of T)表达式中涉及 a 时,编译器在内部将相等运算符提升(或者,我想,更准确地说,“提升”)Nullable(Of T)版本,我认为从技术上讲,它不是“隐式转换。” 因此,它不会生成编译时错误。因为元素作为 a 传递parameter给版本中的函数,所以MethodSyntax没有应用提升运算符,然后编译器会捕获隐式转换语法。

于 2015-06-10T20:24:45.710 回答
2

感谢@David W 的评论,他们帮我指出了答案!

方法语法:

.Where方法具体就是方法System.Linq.Enumerable.Where,它指定谓词参数是一个返回Boolean值的labmba函数。正如@GSerg 所说,比较将返回一个Boolean?值,因此编译器会抛出错误。

MSDN:扩展方法

查询语法

相反,Where查询语法的子句接受“表达式”作为条件参数。

关于这个条件参数,MSDN 继续说:

Where 子句中使用的表达式必须计算为布尔值或等效的布尔值,例如当其值为 0 时计算为 False 的整数。

MSDN:Where 子句

结论

换句话说,使用查询语法,表达式将始终被计算。结果,Option Strict将不起作用,因为编译器正在考虑计算表达式的结果,而不是表达式本身的数据类型。

于 2015-06-10T21:50:16.523 回答