如果我有一个对象列表(例如List(Of Foo)
),并且想要获得列表中各个元素中特定属性的最小值,则可以使用类似的东西:
listOfFoo.Min(Function(i) i.Id)
没问题。现在,如果列表恰好为空,则上面的代码将不起作用。所以,我使用类似的东西:
listOfFoo.DefaultIfEmpty().Min(Function(i) i?.Id).GetValueOrDefault()
这也可以很好地工作 ,直到列表变成通用对象列表 ,然后它开始返回非常奇怪的结果。
重现该问题的代码:
Class Foo
Public Property Id As Integer
End Class
Class Bar
Public Property Id As Integer
End Class
Function GetMin(list As List(Of Foo)) As Integer
Return list.DefaultIfEmpty().Min(Function(i) i?.Id).GetValueOrDefault()
End Function
Function GetMin(Of T As Bar)(list As List(Of T)) As Integer
Return list.DefaultIfEmpty().Min(Function(i) i?.Id).GetValueOrDefault()
End Function
Sub Main()
Dim fooList As New List(Of Foo) From {New Foo() With {.Id = 2}, New Foo() With {.Id = 3}}
Dim min = GetMin(fooList)
Console.WriteLine(min) ' 2 --> Great!
Dim barList As New List(Of Bar) From {New Bar() With {.Id = 2}, New Bar() With {.Id = 3}}
Dim min2 = GetMin(Of Bar)(barList)
Console.WriteLine(min2) ' 12 --> Huh?!!!!
Console.ReadLine()
End Sub
如注释所示,第二个列表返回12
,即使它的值与第一个相同。另外,您会注意到返回的值不是随机的。它随类的属性一起变化。例如,如果我向Bar
添加另一个字符串属性,它将返回606600
而不是12
!
有人对此有解释吗?还是我做错了什么?
更新:我认为这可能是VB.NET中的错误,因为我只是尝试在C#中做同样的事情,并且返回了正确的值。 Here's the C# code,如果有人想看看。我两者都使用.NET 4.5.2,但我也使用VB在.NET 4.6.1上进行了测试,但仍然无法正常工作。
更新#2:
我正在使用VS2015。当我切换到VS2017(相同的.NET版本)时,问题似乎消失了。
答案 0 :(得分:0)
正如我在问题的更新中提到的那样,这似乎可以在特定版本的Visual Studio(在VS2015上生产,而不是在2017年生产)上生产,所以我 认为这是VB编译器中的错误在VS2015中使用。
不幸的是,目前我无法将此项目升级到VS2017,因此,作为一种解决方法,我将替换此行:
min = listOfFoo.DefaultIfEmpty().Min(Function(i) i?.Id).GetValueOrDefault()
使用:
min = If(listOfFoo.Count = 0), 0, listOfFoo.Min(Function(i) i.id)
..它具有相同的功能,尽管在可读性方面我更喜欢前者。