Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
Estendere il set di metodi usati per le query LINQ aggiungendo metodi di estensione all'interfaccia IEnumerable<T> . Oltre alle operazioni standard medie o massime, ad esempio, si crea un metodo di aggregazione personalizzato per calcolare un singolo valore da una sequenza di valori. Si crea anche un metodo che funziona come filtro personalizzato o come trasformazione dati specifica per una sequenza di valori e restituisce una nuova sequenza. Esempi di tali metodi sono Distinct, Skipe Reverse.
Quando si estende l'interfaccia IEnumerable<T> , è possibile applicare i metodi personalizzati a qualsiasi raccolta enumerabile. Per altre informazioni, vedere Metodi di estensione.
Aggiunta di un metodo aggregato
Un metodo di aggregazione calcola un singolo valore da un set di valori. LINQ offre diversi metodi di aggregazione, tra cui Average, Mine Max. È possibile creare un metodo di aggregazione personalizzato aggiungendo un metodo di estensione all'interfaccia IEnumerable<T> .
Nell'esempio di codice seguente viene illustrato come creare un metodo di estensione denominato Median per calcolare una median per una sequenza di numeri di tipo 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
Questo metodo di estensione viene chiamato per qualsiasi raccolta enumerabile nello stesso modo in cui si chiamano altri metodi di aggregazione dall'interfaccia IEnumerable<T> .
Annotazioni
In Visual Basic è possibile usare una chiamata al metodo o una sintassi di query standard per la Aggregate clausola o Group By . Per altre informazioni, vedere Clausola di aggregazione e clausola Group By.
Nell'esempio di codice seguente viene illustrato come usare il Median metodo per una matrice di tipo 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
Sovraccaricare un metodo di aggregazione per accettare vari tipi
È possibile eseguire l'overload del metodo di aggregazione in modo che accetti sequenze di vari tipi. L'approccio standard consiste nel creare un overload per ogni tipo. Un altro approccio consiste nel creare un overload che accetta un tipo generico e lo converte in un tipo specifico usando un delegato. È anche possibile combinare entrambi gli approcci.
Per creare un sovraccarico per ogni tipo
È possibile creare un overload specifico per ogni tipo che si vuole supportare. Nell'esempio di codice seguente viene illustrato un overload del Median metodo per il integer tipo .
' 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
È ora possibile chiamare gli Median overload per entrambi integer i tipi e double , come illustrato nel codice seguente:
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
Per creare un sovraccarico generico
È anche possibile creare un overload che accetta una sequenza di oggetti generici. Questo overload accetta un delegato come parametro e lo usa per convertire una sequenza di oggetti di un tipo generico in un tipo specifico.
Il codice seguente illustra un overload del Median metodo che accetta il Func<T,TResult> delegato come parametro. Questo delegato accetta un oggetto di tipo T generico e restituisce un oggetto di tipo 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
È ora possibile chiamare il Median metodo per una sequenza di oggetti di qualsiasi tipo. Se il tipo non dispone del proprio overload del metodo, è necessario passare un parametro delegato. In Visual Basic è possibile usare un'espressione lambda a questo scopo. Inoltre, se si usa la Aggregate clausola o Group By anziché la chiamata al metodo, è possibile passare qualsiasi valore o espressione presente nell'ambito di questa clausola.
Il codice di esempio seguente illustra come chiamare il Median metodo per una matrice di numeri interi e una matrice di stringhe. Per le stringhe, viene calcolata la mediano per le lunghezze delle stringhe nella matrice. Nell'esempio viene illustrato come passare il Func<T,TResult> parametro delegato al Median metodo per ogni caso.
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
Aggiungere un metodo che restituisca una raccolta
È possibile estendere l'interfaccia IEnumerable<T> con un metodo di query personalizzato che restituisce una sequenza di valori. In questo caso, il metodo deve restituire una raccolta di tipo IEnumerable<T>. Tali metodi possono essere usati per applicare filtri o trasformazioni di dati a una sequenza di valori.
Nell'esempio seguente viene illustrato come creare un metodo di estensione denominato AlternateElements che restituisce ogni altro elemento di una raccolta, a partire dal primo elemento.
' 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
È possibile chiamare questo metodo di estensione per qualsiasi raccolta enumerabile esattamente come si chiamano altri metodi dall'interfaccia IEnumerable<T> , come illustrato nel codice seguente:
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