Partager via


Guide pratique pour ajouter des méthodes personnalisées pour les requêtes LINQ (Visual Basic)

Vous étendez l’ensemble de méthodes que vous utilisez pour les requêtes LINQ en ajoutant des méthodes d’extension à l’interface IEnumerable<T> . Par exemple, en plus des opérations moyennes ou maximales standard, vous créez une méthode d’agrégation personnalisée pour calculer une valeur unique à partir d’une séquence de valeurs. Vous créez également une méthode qui fonctionne comme un filtre personnalisé ou une transformation de données spécifique pour une séquence de valeurs et retourne une nouvelle séquence. Voici des exemples de ces méthodes : Distinct, Skipet Reverse.

Lorsque vous étendez l’interface IEnumerable<T> , vous pouvez appliquer vos méthodes personnalisées à n’importe quelle collection énumérable. Pour plus d’informations, consultez Méthodes d’extension.

Ajout d’une méthode d’agrégation

Une méthode d’agrégation calcule une valeur unique à partir d’un ensemble de valeurs. LINQ fournit plusieurs méthodes d’agrégation, notamment Average, Minet Max. Vous pouvez créer votre propre méthode d’agrégation en ajoutant une méthode d’extension à l’interface IEnumerable<T> .

L’exemple de code suivant montre comment créer une méthode d’extension appelée Median pour calculer une médiane pour une séquence de nombres de types 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

Vous appelez cette méthode d’extension pour toute collection énumérable de la même façon que vous appelez d’autres méthodes d’agrégation à partir de l’interface IEnumerable<T> .

Remarque

Dans Visual Basic, vous pouvez utiliser un appel de méthode ou une syntaxe de requête standard pour la ou Group By la Aggregate clause. Pour plus d’informations, consultez Clause Aggregate et Clause Group By.

L’exemple de code suivant montre comment utiliser la Median méthode pour un tableau de 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

Surcharge d’une méthode d’agrégation pour accepter différents types

Vous pouvez surcharger votre méthode d’agrégation afin qu’elle accepte des séquences de différents types. L’approche standard consiste à créer une surcharge pour chaque type. Une autre approche consiste à créer une surcharge qui prendra un type générique et à la convertir en un type spécifique à l’aide d’un délégué. Vous pouvez également combiner les deux approches.

Pour créer une surcharge pour chaque type

Vous pouvez créer une surcharge spécifique pour chaque type que vous souhaitez prendre en charge. L’exemple de code suivant montre une surcharge de la Median méthode pour le 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

Vous pouvez maintenant appeler les Median surcharges pour les deux integer types double , comme indiqué dans le code suivant :

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

Pour créer une surcharge générique

Vous pouvez également créer une surcharge qui accepte une séquence d’objets génériques. Cette surcharge prend un délégué comme paramètre et l’utilise pour convertir une séquence d’objets d’un type générique en un type spécifique.

Le code suivant montre une surcharge de la Median méthode qui prend le Func<T,TResult> délégué en tant que paramètre. Ce délégué prend un objet de type T générique et retourne un objet de 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

Vous pouvez maintenant appeler la Median méthode pour une séquence d’objets de n’importe quel type. Si le type n’a pas sa propre surcharge de méthode, vous devez passer un paramètre délégué. Dans Visual Basic, vous pouvez utiliser une expression lambda à cet effet. En outre, si vous utilisez la ou Group By la Aggregate clause au lieu de l’appel de méthode, vous pouvez passer n’importe quelle valeur ou expression qui se trouve dans l’étendue de cette clause.

L’exemple de code suivant montre comment appeler la Median méthode pour un tableau d’entiers et un tableau de chaînes. Pour les chaînes, la médiane pour les longueurs de chaînes du tableau est calculée. L’exemple montre comment transmettre le Func<T,TResult> paramètre délégué à la Median méthode pour chaque cas.

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

Ajout d’une méthode qui retourne une collection

Vous pouvez étendre l’interface IEnumerable<T> avec une méthode de requête personnalisée qui retourne une séquence de valeurs. Dans ce cas, la méthode doit retourner une collection de type IEnumerable<T>. Ces méthodes peuvent être utilisées pour appliquer des filtres ou des transformations de données à une séquence de valeurs.

L’exemple suivant montre comment créer une méthode d’extension nommée AlternateElements qui retourne tous les autres éléments d’une collection, à partir du premier élément.

' 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

Vous pouvez appeler cette méthode d’extension pour n’importe quelle collection énumérable comme vous le feriez pour appeler d’autres méthodes à partir de l’interface IEnumerable<T> , comme illustré dans le code suivant :

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

Voir aussi