隐式转换:Nullable(Of T)=> T | VB.NET LINQ查询语法与方法语法

时间:2015-06-10 19:02:31

标签: vb.net linq implicit-conversion linq-query-syntax linq-method-syntax

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

2 个答案:

答案 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?值,因此编译器会抛出错误。

MSDN: Extension Method

查询语法

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

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

  

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

MSDN: Where Clause

<强>结论

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