最近我需要基于特定的Object属性从List中提取不同的值(在这种情况下,是DateTime
格式的时间戳)所以在一些粗略的Googling之后我遇到了一个SO线程,其中有人提供了名为' DistinctBy()'它遍历一个集合并返回具有不同属性值的项目。代码如下;
<Extension()> _
Public Function DistinctBy(Of TSource, TKey)(source As IEnumerable(Of TSource), keySelector As Func(Of TSource, TKey)) As IEnumerable(Of TSource)
Dim seenKeys As New HashSet(Of TKey)()
For Each element As TSource In source
If seenKeys.Add(keySelector(element)) Then
Return CType(element, Global.System.Collections.Generic.IEnumerable(Of TSource))
End If
Next
End Function
代码最初是在C#中,但我使用代码转换器将其更改为Visual Basic。也就是说,我在VS2013中收到警告,说明该函数并未在所有代码路径上返回值。我知道错误的含义以及在正常情况下如何修复错误。但是,我不确定如何继续,因为这是一个返回IEnumerable对象的函数。我不熟悉IEnumerable函数是如何工作的,我甚至都不知道函数是否会起作用!
任何人都可以澄清这种情况吗?
答案 0 :(得分:1)
在初始C#代码中(可能)是一个迭代器方法(使用yield
)
它也应该在VB.Net中为您提供,因此正确的转换将是
<Extension()> _
Public Iterator Function DistinctBy(Of TSource, TKey)(source As IEnumerable(Of TSource), keySelector As Func(Of TSource, TKey)) As IEnumerable(Of TSource)
Dim seenKeys As New HashSet(Of TKey)()
For Each element As TSource In source
If seenKeys.Add(keySelector(element)) Then
Yield element
End If
Next
End Function
答案 1 :(得分:1)
original code包含yield
关键字的状态机。同时VB.NET supports it。它是着名的延迟执行LINQ。
<Extension()> _
Public Iterator Function DistinctBy(Of TSource, TKey)(source As IEnumerable(Of TSource), keySelector As Func(Of TSource, TKey)) As IEnumerable(Of TSource)
Dim seenKeys As New HashSet(Of TKey)()
For Each element As TSource In source
If seenKeys.Add(keySelector(element)) Then
Yield element
End If
Next
End Function
如果您必须支持不知道Yield
的.NET版本,您可以使用此方法一次性返回所有项目:
<Extension()> _
Public Function DistinctBy(Of TSource, TKey)(source As IEnumerable(Of TSource), keySelector As Func(Of TSource, TKey)) As IEnumerable(Of TSource)
Dim seenKeys As New HashSet(Of TKey)()
Dim list = new List(Of TSource)
For Each element As TSource In source
If seenKeys.Add(keySelector(element))
list.Add(element)
End If
Next
return list
End Function