2017-02-21 121 views
0

我有時會發現自己編寫了兩個版本的相同函數,可以獲取多個屬性中某個屬性具有特定值的成員數。我一直在看func和其他的例子,看看我是否可以編寫一個單一的函數來進行計數,其中的值與某個對象的幾個屬性之一匹配。感覺應該有一種方法...在lambda表達式中使用的Lambda屬性值選擇器

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

您可以返回字典從單一功能不同的計數在它爲不同的密鑰。 – Lali

+0

你是對的,但是這個功能的目標是隻返回一個屬性的計數。我只需要根據任一財產計算一次。只是想知道是否有一種模式可以編寫一個函數,它可以從一個集合中的特定對象的任何屬性中獲得一個計數。 – Geekn

+0

然後,您還需要傳遞該屬性。目前你只傳遞值,因爲函數已經知道檢查屬性 – Lali

回答

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")) 

附:你到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)) 
+0

這正是我所希望的。感謝您花時間。 – Geekn