Dela via


Anvisningar: Lägga till anpassade metoder för LINQ-frågor (Visual Basic)

Du utökar den uppsättning metoder som du använder för LINQ-frågor genom att lägga till tilläggsmetoder i IEnumerable<T> gränssnittet. Utöver standardåtgärderna för genomsnitt eller maximalt skapar du till exempel en anpassad aggregeringsmetod för att beräkna ett enda värde från en sekvens med värden. Du skapar också en metod som fungerar som ett anpassat filter eller en specifik datatransformering för en sekvens med värden och returnerar en ny sekvens. Exempel på sådana metoder är Distinct, Skipoch Reverse.

När du utökar IEnumerable<T> gränssnittet kan du använda dina anpassade metoder för alla uppräkningsbara samlingar. Mer information finns i Tilläggsmetoder.

Lägga till en aggregeringsmetod

En aggregeringsmetod beräknar ett enda värde från en uppsättning värden. LINQ innehåller flera aggregeringsmetoder, inklusive Average, Minoch Max. Du kan skapa en egen aggregeringsmetod genom att lägga till en tilläggsmetod i IEnumerable<T> gränssnittet.

I följande kodexempel visas hur du skapar en tilläggsmetod med namnet Median för att beräkna en median för en sekvens med tal av typen 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

Du anropar den här tilläggsmetoden för en uppräkningsbar samling på samma sätt som du anropar andra aggregeringsmetoder från IEnumerable<T> gränssnittet.

Kommentar

I Visual Basic kan du antingen använda ett metodanrop eller standardfrågesyntax för Aggregate eller Group By -satsen. Mer information finns i Aggregerad sats och Gruppera efter-sats.

Följande kodexempel visar hur du använder Median metoden för en matris av typen 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

Överbelasta en aggregeringsmetod för att acceptera olika typer

Du kan överbelasta din aggregeringsmetod så att den accepterar sekvenser av olika typer. Standardmetoden är att skapa en överlagring för varje typ. En annan metod är att skapa en överlagring som tar en allmän typ och konverterar den till en viss typ med hjälp av ett ombud. Du kan också kombinera båda metoderna.

Skapa en överlagring för varje typ

Du kan skapa en specifik överlagring för varje typ som du vill stödja. I följande kodexempel visas en överlagring av Median metoden för integer typen.

' 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

Nu kan du anropa överlagringarna Median för båda integer typerna, double som du ser i följande kod:

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

Skapa en allmän överlagring

Du kan också skapa en överlagring som accepterar en sekvens med generiska objekt. Den här överlagringen tar ett ombud som en parameter och använder den för att konvertera en sekvens av objekt av allmän typ till en viss typ.

Följande kod visar en överlagring av metoden Median som tar ombudet Func<T,TResult> som en parameter. Det här ombudet tar ett objekt av allmän typ T och returnerar ett objekt av typen 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

Nu kan du anropa Median metoden för en sekvens av objekt av vilken typ som helst. Om typen inte har en egen metodöverlagring måste du skicka en ombudsparameter. I Visual Basic kan du använda ett lambda-uttryck för det här ändamålet. Om du använder Aggregate satsen eller Group By i stället för metodanropet kan du också skicka valfritt värde eller uttryck som finns i omfånget för den här satsen.

Följande exempelkod visar hur du anropar Median metoden för en matris med heltal och en matris med strängar. För strängar beräknas medianen för längden på strängarna i matrisen. Exemplet visar hur du skickar Func<T,TResult> delegatparametern till Median metoden för varje ärende.

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

Lägga till en metod som returnerar en samling

Du kan utöka IEnumerable<T> gränssnittet med en anpassad frågemetod som returnerar en sekvens med värden. I det här fallet måste metoden returnera en samling av typen IEnumerable<T>. Sådana metoder kan användas för att tillämpa filter eller datatransformering på en sekvens med värden.

I följande exempel visas hur du skapar en tilläggsmetod med namnet AlternateElements som returnerar alla andra element i en samling, med början från det första elementet.

' 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

Du kan anropa den här tilläggsmetoden för valfri uppräkningsbar samling precis som du anropar andra metoder från IEnumerable<T> gränssnittet, som du ser i följande kod:

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

Se även