VB.NET - 如何纠正“.DistinctBy() 不 return 所有代码路径上的值”警告

VB.NET - how to rectify ".DistinctBy() doesn't return a value on all code paths" warning

最近我需要根据特定对象 属性(在本例中,DateTime 格式的时间戳)从列表中提取不同值的方法,因此在粗略谷歌搜索后,我遇到了一个SO 线程,其中有人提供了一个名为 'DistinctBy()' 的扩展,它遍历一个集合和 return 具有不同 属性 值的项目。代码如下;

<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 中收到一条警告,指出该函数没有 return 所有代码路径上的值。我知道错误的含义以及在正常情况下如何修复它们。但是,考虑到这是一个 return 是 IEnumerable 对象的函数,我不确定如何继续。我不熟悉 IEnumerable 函数的工作原理,我什至不知道该函数是否可以工作!

任何人都可以澄清这种情况吗?

它(可能)是初始 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

original code contained state machines with the yield keyword. Meanwhile 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 版本,您可以使用这种方法 returns 一次所有项目:

<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