Delen via


Procedure: Aangepaste methoden toevoegen voor LINQ-query's (Visual Basic)

U kunt de set methoden die u gebruikt voor LINQ-query's uitbreiden door extensiemethoden toe te voegen aan de IEnumerable<T> interface. Naast de standaardgemiddelde of maximumbewerkingen maakt u bijvoorbeeld een aangepaste statistische methode om één waarde te berekenen op basis van een reeks waarden. U maakt ook een methode die werkt als een aangepast filter of een specifieke gegevenstransformatie voor een reeks waarden en retourneert een nieuwe reeks. Voorbeelden van dergelijke methoden zijn Distinct, Skipen Reverse.

Wanneer u de IEnumerable<T> interface uitbreidt, kunt u uw aangepaste methoden toepassen op elke enumerable verzameling. Zie Extensiemethoden voor meer informatie.

Een statistische methode toevoegen

Met een statistische methode wordt één waarde berekend op basis van een set waarden. LINQ biedt verschillende statistische methoden, waaronder Average, Minen Max. U kunt uw eigen statistische methode maken door een extensiemethode toe te voegen aan de IEnumerable<T> interface.

In het volgende codevoorbeeld ziet u hoe u een extensiemethode maakt die wordt aangeroepen Median om een mediaan te berekenen voor een reeks getallen van het type 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

U roept deze extensiemethode aan voor elke inventariserbare verzameling op dezelfde manier als u andere statistische methoden aanroept vanuit de IEnumerable<T> interface.

Notitie

In Visual Basic kunt u een methode-aanroep of standaardquerysyntaxis voor de Aggregate of Group By component gebruiken. Zie Aggregaties enGroup By-component voor meer informatie.

In het volgende codevoorbeeld ziet u hoe u de Median methode gebruikt voor een matrix van het type 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

Een statistische methode overbelasten om verschillende typen te accepteren

U kunt uw statistische methode overbelasten, zodat deze reeksen van verschillende typen accepteert. De standaardmethode is het creëren van een overbelasting voor elk type. Een andere benadering is het maken van een overbelasting die een algemeen type neemt en converteert naar een specifiek type met behulp van een gemachtigde. U kunt beide benaderingen ook combineren.

Een overbelasting maken voor elk type

U kunt een specifieke overbelasting maken voor elk type dat u wilt ondersteunen. In het volgende codevoorbeeld ziet u een overbelasting van de Median methode voor het integer type.

' 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

U kunt nu de Median overbelastingen voor beide integer typen double aanroepen, zoals wordt weergegeven in de volgende code:

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

Een algemene overbelasting maken

U kunt ook een overbelasting maken die een reeks algemene objecten accepteert. Deze overbelasting neemt een gemachtigde als parameter en gebruikt deze om een reeks objecten van een algemeen type te converteren naar een specifiek type.

De volgende code toont een overbelasting van de Median methode die de Func<T,TResult> gemachtigde als parameter gebruikt. Deze gemachtigde neemt een object van algemeen type T en retourneert een object van het type 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

U kunt nu de Median methode aanroepen voor een reeks objecten van elk type. Als het type geen eigen overbelasting van de methode heeft, moet u een gemachtigde parameter doorgeven. In Visual Basic kunt u hiervoor een lambda-expressie gebruiken. Als u de Aggregate of Group By component gebruikt in plaats van de methode-aanroep, kunt u ook elke waarde of expressie doorgeven die binnen het bereik van deze component valt.

In de volgende voorbeeldcode ziet u hoe u de Median methode aanroept voor een matrix met gehele getallen en een matrix met tekenreeksen. Voor tekenreeksen wordt de mediaan voor de lengte van tekenreeksen in de matrix berekend. In het voorbeeld ziet u hoe u de Func<T,TResult> parameter voor gedelegeerden doorgeeft aan de Median methode voor elke case.

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

Een methode toevoegen die een verzameling retourneert

U kunt de IEnumerable<T> interface uitbreiden met een aangepaste querymethode die een reeks waarden retourneert. In dit geval moet de methode een verzameling van het type IEnumerable<T>retourneren. Dergelijke methoden kunnen worden gebruikt om filters of gegevenstransformaties toe te passen op een reeks waarden.

In het volgende voorbeeld ziet u hoe u een extensiemethode maakt met de naam AlternateElements die elk ander element in een verzameling retourneert, te beginnen met het eerste element.

' 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

U kunt deze extensiemethode aanroepen voor elke enumerable verzameling, net zoals u andere methoden aanroept vanuit de IEnumerable<T> interface, zoals wordt weergegeven in de volgende code:

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

Zie ook