操作說明:新增 LINQ 查詢的自訂方法 (Visual Basic)
您可以藉由將擴充方法新增至 IEnumerable<T> 介面,來擴充您可以用於 LINQ 查詢的方法集合。 例如,除了標準平均值或最大運算,您可以建立自訂的彙總方法來計算一系列值的單一值。 您也可以建立一個方法,用為自訂篩選器或一系列值的特定資料轉換,並傳回新的序列。 這類方法的範例包括 Distinct、Skip 和 Reverse。
當您延伸 IEnumerable<T> 介面時,可將自訂方法套用至任何可列舉的集合。 如需詳細資訊,請參閱擴充方法。
新增彙總方法
彙總方法會計算一組值的單一值。 LINQ 提供數種彙總方法,包括 Average、Min 和 Max。 您可將擴充方法新增至 IEnumerable<T> 介面,建立自己的彙總方法。
下列程式碼範例示範如何建立呼叫 Median
的擴充方法,來計算一系列類型為 double
的中位數。
Imports System.Runtime.CompilerServices
Module LINQExtension
' Extension method for the IEnumerable(of T) interface.
' The method accepts only values of the Double type.
<Extension()>
Function Median(ByVal source As IEnumerable(Of Double)) As Double
If Not source.Any() Then
Throw New InvalidOperationException("Cannot compute median for an empty set.")
End If
Dim sortedSource = (From number In source
Order By number).ToList()
Dim itemIndex = sortedSource.Count \ 2
If sortedSource.Count Mod 2 = 0 Then
' Even number of items in list.
Return (sortedSource(itemIndex) + sortedSource(itemIndex - 1)) / 2
Else
' Odd number of items in list.
Return sortedSource(itemIndex)
End If
End Function
End Module
您可以使用從 IEnumerable<T> 介面呼叫其他彙總方法同樣的方式,為任何可列舉集合呼叫此擴充方法。
注意
在 Visual Basic 中,您可以使用 Aggregate
或 Group By
子句的方法呼叫或標準查詢語法。 如需詳細資訊,請參閱 Aggregate 子句和 Group By 子句。
下列程式碼範例示範如何使用 Median
方法處理 double
類型的陣列。
Dim numbers() As Double = {1.9, 2, 8, 4, 5.7, 6, 7.2, 0}
Dim query = Aggregate num In numbers Into Median()
Console.WriteLine("Double: Median = " & query)
' This code produces the following output:
'
' Double: Median = 4.85
多載彙總方法以接受各種類型
您可以多載自己的彙總方法,讓它接受各種類型的序列。 標準方法是為每種類型建立多載。 另一種方法是建立採用泛型型別的多載,使用委派將它轉換成特定的類型。 您也可以結合這兩種方法。
為每種類型建立多載
您可以為想要支援的每種類型建立特定的多載。 下列程式碼範例示範適合 integer
類型之 Median
方法的多載。
' Integer overload
<Extension()>
Function Median(ByVal source As IEnumerable(Of Integer)) As Double
Return Aggregate num In source Select CDbl(num) Into med = Median()
End Function
您現在可以呼叫 integer
和 double
類型的 Median
多載,如下列程式碼所示︰
Dim numbers1() As Double = {1.9, 2, 8, 4, 5.7, 6, 7.2, 0}
Dim query1 = Aggregate num In numbers1 Into Median()
Console.WriteLine("Double: Median = " & query1)
Dim numbers2() As Integer = {1, 2, 3, 4, 5}
Dim query2 = Aggregate num In numbers2 Into Median()
Console.WriteLine("Integer: Median = " & query2)
' This code produces the following output:
'
' Double: Median = 4.85
' Integer: Median = 3
建立一般多載
您也可以建立接受一系列泛型物件的多載。 這個多載會接受委派作為參數,並使用它將泛型型別物件的序列轉換成特定的類型。
下列程式碼顯示 Median
方法的多載,接受 Func<T,TResult> 委派為參數。 這個委派會接受泛型型別 T
的物件,並傳回 double
類型的物件。
' Generic overload.
<Extension()>
Function Median(Of T)(ByVal source As IEnumerable(Of T),
ByVal selector As Func(Of T, Double)) As Double
Return Aggregate num In source Select selector(num) Into med = Median()
End Function
您現在可以針對一系列的類型物件呼叫 Median
方法。 如果類型沒有自己的方法多載,您就必須傳遞委派參數。 在 Visual Basic 中,您可以針對此目的使用 Lambda 運算式。 另外,如果您使用 Aggregate
或 Group By
子句而不是方法呼叫,您可以傳遞此子句範圍內的任何值或運算式。
下列程式碼範例示範如何呼叫 Median
方法,處理整數陣列及字串陣列。 針對字串,會計算陣列字串長度的中間值。 此範例會示範如何將 Func<T,TResult> 委派參數傳遞至每個案例的 Median
方法。
Dim numbers3() As Integer = {1, 2, 3, 4, 5}
' You can use num as a parameter for the Median method
' so that the compiler will implicitly convert its value to double.
' If there is no implicit conversion, the compiler will
' display an error message.
Dim query3 = Aggregate num In numbers3 Into Median(num)
Console.WriteLine("Integer: Median = " & query3)
Dim numbers4() As String = {"one", "two", "three", "four", "five"}
' With the generic overload, you can also use numeric properties of objects.
Dim query4 = Aggregate str In numbers4 Into Median(str.Length)
Console.WriteLine("String: Median = " & query4)
' This code produces the following output:
'
' Integer: Median = 3
' String: Median = 4
新增傳回集合的方法
您可以使用傳回一系列值的自訂查詢方法來延伸 IEnumerable<T> 介面。 在此情況下,方法必須傳回型別 IEnumerable<T> 的集合。 此等方法可用來將篩選條件或資料轉換套用至一系列的值。
下例示範如何建立名為 AlternateElements
的擴充方法,傳回集合中的每隔個項目,從第一個項目開始。
' Extension method for the IEnumerable(of T) interface.
' The method returns every other element of a sequence.
<Extension()>
Iterator Function AlternateElements(Of T)(
ByVal source As IEnumerable(Of T)
) As IEnumerable(Of T)
Dim i = 0
For Each element In source
If (i Mod 2 = 0) Then
Yield element
End If
i = i + 1
Next
End Function
您可為任何可列舉集合呼叫此擴充方法,就和您從 IEnumerable<T> 介面呼叫其他方法一樣,如下列程式碼所示:
Dim strings() As String = {"a", "b", "c", "d", "e"}
Dim query5 = strings.AlternateElements()
For Each element In query5
Console.WriteLine(element)
Next
' This code produces the following output:
'
' a
' c
' e