LINQ是否在VB.NET中进行短路评估?

时间:2012-01-05 17:23:57

标签: vb.net linq null short-circuiting

我们今天在这行代码中遇到Nullable object must have a value错误:

list = From x In Me Where x.FooDate.HasValue AndAlso x.FooDate.Value.Date >= barDate

有趣的是,我确信这曾经很好地工作(并且在底层数据中总是存在一些空值)。从逻辑上讲,它看起来很好。检查HasValueAndAlso 看起来,好像它们会保护我们免受任何空危险。

但突然间他们似乎没有。我错过了什么吗?

好的,我们可以纠正它,这消除了错误:

list = From x In Me Where If(x.FooDate.HasValue, x.FooDate.Value.Date >= barDate,False)

但这对我来说不太可读。有什么想法吗?

更新......和忏悔
在简化上面的代码来缩短行时,我遗漏了一小部分代码。最初的问题应该是这样的:

list = From x In Me Where x.FooDate.HasValue AndAlso x.FooDate.Value.Date >= fromDate And x.FooDate.Value.Date <= toDate

由于短路和运算符优先级的规则(对于我自己的很久以前的问题,outlined in an answer)我需要在指令的第二部分附加括号,以便停止LINQ评估第二部分{{ 1}}:

x.FooDate.Value.Date

感谢两个答案,即抛出快速测试代码以验证LINQ是否真的服从AndAlso并迫使我更仔细地查看原始问题。

2 个答案:

答案 0 :(得分:1)

我非常确定您的查询是安全的,至少遵循以下示例代码:

Dim dateList As New List(Of Nullable(Of Date))
For i As Int32 = 0 To 12
    If (i Mod 3 = 0) Then
        dateList.Add(Nothing)
    Else
        dateList.Add(New Date(2012, i, 1))
    End If
Next
Dim july = New Date(2012, 7, 1)
Dim fromJuly = (From m In dateList
      Where m.HasValue AndAlso m.Value.Date >= july).ToList

注意:如果我用AndAlso替换And,我会得到您的例外。

所以问题必定在其他地方。请告诉我们你的课程。

答案 1 :(得分:1)

它应该工作。我写了这段代码,即使将barDate设置为Nothing,它也能很好用。

Sub Main()

    Dim barDate As Nullable(Of DateTime) = Nothing

    Dim List = From x In GetDates() Where x.FooDate.HasValue AndAlso x.FooDate.Value.Date > barDate

    Console.WriteLine(List.Count())

End Sub

Function GetDates() As List(Of Foo)
    Dim l = New List(Of Foo)
    l.Add(New Foo With {.FooDate = DateTime.Now})
    l.Add(New Foo)
    Return l
End Function

Class Foo
    Private m_fooDate As DateTime?
    Public Property FooDate() As DateTime?
        Get
            Return m_fooDate
        End Get
        Set(ByVal value As DateTime?)
            m_fooDate = value
        End Set
    End Property

End Class