lambda表达式中使用的Lambda属性值选择器

时间:2017-02-21 12:50:02

标签: vb.net linq

我有时会发现自己编写了同一个函数的两个版本,它们获取了一些成员的数量,其中一个属性具有特定值。我一直在查看func和其他示例,看看我是否可以编写单个函数来进行计数,其中值与对象的几个属性之一匹配。感觉应该有办法...

Module Test
    Private _students As New List(Of Student)
    Sub Main()
        _students.Add(New Student(1, "Stephen"))
        _students.Add(New Student(2, "Jenny"))

        ' I'd like to replace the following lines...

        Console.WriteLine(GetCountByID(1))
        Console.WriteLine(GetCountByName("Stephen"))

        ' with a single function that could be used like below.

        'Console.WriteLine(GetCountByType(1, Student.ID))
        'Console.WriteLine(GetCountByType("Stephen", Student.Name))

        Console.ReadLine()
    End Sub

    Public Function GetCountByID(ByVal id As Integer) As Integer
        Return _students.Where(Function(s) s.ID = id).ToList.Count
    End Function
    Public Function GetCountByName(ByVal name As String) As Integer
        Return _students.Where(Function(s) s.Name = name).ToList.Count
    End Function

    ' I know this is wrong below but I'm just writing it like I'm thinking about it in my head

    'Public Function GetCountByType(ByVal value As Object, selectorProperty As Func(Of Student)) As Integer
    ' Return _students.Where(Function(s) s.selectorProperty = value).ToList.Count
    'End Function

    Public Class Student
        Public Property ID As Integer
        Public Property Name As String
        Public Sub New(ByVal id As Integer, ByVal name As String)
            Me.ID = id
            Me.Name = name
        End Sub
    End Class 
End Module

1 个答案:

答案 0 :(得分:1)

你沿着正确的方向行,但你的Func需要返回一个对象。 然而,最好将其设为通用,类型必须是IComparable类型,以便您可以检查与目标值的相等性。

Public Function GetCountBy(Of T As IComparable)(selector As Func(Of Student, T), value As T) As Integer
    Return _students.Where(Function(s) selector(s).CompareTo(value) = 0).Count()
End Function

Console.WriteLine(GetCountBy(Function(s) s.ID, 1))
Console.WriteLine(GetCountBy(Function(s) s.Name, "Stephen"))

P.S。您对ToList()的调用是不必要的

但是一旦你走了这么远,你也可以传递完整的谓词而不是选择器函数和值

Public Function CountWhere(predicate As Func(Of Student, Boolean))
    Return _students.Where(predicate).Count()
End Function
Console.WriteLine(CountWhere(Function(s) s.ID = 1))

您可以进一步概括这一点,因此它适用于任何集合而不仅仅是学生,如果您愿意,可以将其作为扩展功能

Public Function CountWhere(Of T)(coll As IEnumerable(Of T), predicate As Func(Of T, Boolean))
    Return coll.Where(predicate).Count()
End Function
Console.WriteLine(CountWhere(_students, Function(s) s.ID = 1))