VB.NET - 如何纠正" .DistinctBy()不会在所有代码路径上返回一个值"警告

时间:2016-08-05 10:17:14

标签: vb.net ienumerable

最近我需要基于特定的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函数是如何工作的,我甚至都不知道函数是否会起作用!

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

2 个答案:

答案 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