我有时会发现自己编写了同一个函数的两个版本,它们获取了一些成员的数量,其中一个属性具有特定值。我一直在查看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
答案 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))