Sdílet prostřednictvím


Postupy: Přidání vlastních metod pro dotazy LINQ (Visual Basic)

Sadu metod, které používáte pro dotazy LINQ, rozšíříte přidáním rozšiřujících metod do IEnumerable<T> rozhraní. Kromě standardních průměrných nebo maximálních operací například vytvoříte vlastní agregační metodu pro výpočet jedné hodnoty z posloupnosti hodnot. Vytvoříte také metodu, která funguje jako vlastní filtr nebo konkrétní transformace dat pro sekvenci hodnot a vrací novou sekvenci. Příklady takových metod jsou Distinct, Skipa Reverse.

Když rozhraní rozšíříte IEnumerable<T> , můžete vlastní metody použít na libovolnou výčtové kolekce. Další informace naleznete v tématu Metody rozšíření.

Přidání agregační metody

Agregační metoda vypočítá jednu hodnotu ze sady hodnot. LINQ poskytuje několik agregačních metod, včetně Average, Mina Max. Vlastní agregační metodu můžete vytvořit přidáním rozšiřující metody do IEnumerable<T> rozhraní.

Následující příklad kódu ukazuje, jak vytvořit rozšiřující metodu volanou Median pro výpočet mediánu pro sekvenci čísel typu 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

Tuto metodu rozšíření voláte pro všechny výčtové kolekce stejným způsobem, jakým voláte jiné agregační metody z IEnumerable<T> rozhraní.

Poznámka:

V jazyce Visual Basic můžete buď použít volání metody, nebo standardní syntaxi dotazu pro Aggregate klauzuli nebo Group By klauzuli. Další informace naleznete v tématu Agregační klauzule a klauzule Group By.

Následující příklad kódu ukazuje, jak použít metodu Median pro pole typu 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

Přetížení agregační metody pro příjem různých typů

Agregační metodu můžete přetížit tak, aby přijímala sekvence různých typů. Standardním přístupem je vytvoření přetížení pro každý typ. Dalším přístupem je vytvoření přetížení, které bude mít obecný typ a převést ho na konkrétní typ pomocí delegáta. Můžete také kombinovat oba přístupy.

Vytvoření přetížení pro každý typ

Pro každý typ, který chcete podporovat, můžete vytvořit konkrétní přetížení. Následující příklad kódu ukazuje přetížení Median metody pro integer typ.

' 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

Nyní můžete volat Median přetížení pro oba integer typy double , jak je znázorněno v následujícím kódu:

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

Vytvoření obecného přetížení

Můžete také vytvořit přetížení, které přijímá posloupnost obecných objektů. Toto přetížení přebírá delegáta jako parametr a používá ho k převodu posloupnosti objektů obecného typu na určitý typ.

Následující kód ukazuje přetížení Median metody, která přebírá delegáta Func<T,TResult> jako parametr. Tento delegát přebírá objekt obecného typu T a vrací objekt typu 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

Nyní můžete volat metodu Median pro posloupnost objektů libovolného typu. Pokud typ nemá vlastní přetížení metody, musíte předat parametr delegáta. V jazyce Visual Basic můžete pro tento účel použít výraz lambda. Pokud místo volání metody použijete Aggregate klauzuli nebo Group By klauzuli, můžete předat libovolnou hodnotu nebo výraz, který je v oboru této klauzule.

Následující příklad kódu ukazuje, jak volat metodu Median pro pole celých čísel a pole řetězců. U řetězců se vypočítá medián délky řetězců v poli. Příklad ukazuje, jak předat Func<T,TResult> parametr delegáta Median metodě pro každý případ.

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

Přidání metody, která vrací kolekci

Rozhraní můžete rozšířit IEnumerable<T> vlastní metodou dotazu, která vrací posloupnost hodnot. V tomto případě musí metoda vrátit kolekci typu IEnumerable<T>. Tyto metody lze použít k použití filtrů nebo transformací dat na sekvenci hodnot.

Následující příklad ukazuje, jak vytvořit rozšiřující metodu s názvem AlternateElements , která vrací všechny ostatní prvky v kolekci počínaje prvním prvkem.

' 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

Tuto metodu rozšíření můžete volat pro libovolnou výčet kolekcí stejně, jako byste volali jiné metody z IEnumerable<T> rozhraní, jak je znázorněno v následujícím kódu:

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

Viz také