VB.NET - 如何纠正".DistinctBy() doesn't return a value on all code paths"警告



最近我需要一种方法来根据特定的Object属性(在本例中,是DateTime格式的时间戳)从List中提取不同的值,所以在粗略的谷歌搜索后,我发现了一个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函数是如何工作的,我甚至不知道这个函数是否会工作!

有人能澄清一下这种情况吗?

原始代码包含带有yield关键字的状态机。同时VB.NET支持它,它是著名的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

在最初的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

最新更新