Aracılığıyla paylaş


Nasıl yapılır: LINQ sorguları için özel yöntemler ekleme

Uzantı yöntemleri ekleyerek LINQ sorguları için kullanabileceğiniz yöntemler kümesi genişletebilirsiniz IEnumerable<T> arabirimi.Örneğin, standart ortalama veya en fazla işlemlerinin yanı sıra, değerleri bir dizi tek bir değeri hesaplamak için özel bir toplama yöntemi oluşturabilirsiniz.Özel bir filtre ya da değerler dizisi için belirli veri Dönüşüm olarak çalışır ve yeni bir sıra döndüren bir yöntem de oluşturabilirsiniz.Bu tür yöntemler örnekler Distinct, Skip<TSource>, ve Reverse<TSource>.

Genişlettiğinizde IEnumerable<T> arabirimi, özel yöntemleriniz için herhangi bir sýralanabilir koleksiyon uygulayabilirsiniz.Daha fazla bilgi için, bkz. Uzantı yöntemleri (C# Programlama Kılavuzu) veya Uzantı yöntemleri (Visual Basic).

Bir toplama yöntemi ekleme

Bir toplama yöntemi, bir değerler kümesini tek bir değeri hesaplar.LINQ sağlar birkaç toplama yöntemleri Average, Min, ve Max.Bir uzantı yöntemi ekleyerek kendi toplama yöntemi oluşturabilirsiniz IEnumerable<T> arabirimi.

Aşağıdaki kod örneği adlı bir uzantısı yöntemi nasıl oluşturulacağını gösterir Median bir dizi sayı türü için bir orta hesaplamak için 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 source.Count = 0 Then
            Throw New InvalidOperationException("Cannot compute median for an empty set.")
        End If

        Dim sortedSource = From number In source 
                           Order By number

        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
public static class LINQExtension
{
    public static double Median(this IEnumerable<double> source)
    {
        if (source.Count() == 0)
        {
            throw new InvalidOperationException("Cannot compute median for an empty set.");
        }

        var sortedList = from number in source
                         orderby number
                         select number;

        int itemIndex = (int)sortedList.Count() / 2;

        if (sortedList.Count() % 2 == 0)
        {
            // Even number of items.
            return (sortedList.ElementAt(itemIndex) + sortedList.ElementAt(itemIndex - 1)) / 2;
        }
        else
        {
            // Odd number of items.
            return sortedList.ElementAt(itemIndex);
        }
    }
}

Tıpkı diğer toplama yöntemleri çağırmak için herhangi bir sýralanabilir koleksiyon bu uzantı yöntemini çağırın IEnumerable<T> arabirimi.

[!NOT]

Visual Basic'te, ya da bir yöntem çağrısı veya standart sorgu sözdizimini kullanabilirsiniz Aggregate veya Group By yan tümcesi.Daha fazla bilgi için, bkz. Toplam yan tümcesi (Visual Basic) ve Gruplandırma ölçütü yan tümcesi (Visual Basic).

Aşağıdaki kod örneği nasıl kullanılacağını gösteren Median türü bir dizi yöntem double.

        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)



...


        ' This code produces the following output:
        '
        ' Double: Median = 4.85

        double[] numbers1 = { 1.9, 2, 8, 4, 5.7, 6, 7.2, 0 };

        var query1 = numbers1.Median();

        Console.WriteLine("double: Median = " + query1);



...


/*
 This code produces the following output:

 Double: Median = 4.85
*/

Cc981895.collapse_all(tr-tr,VS.110).gifÇeşitli tiplerini kabul edecek bir toplama yöntemi aşırı

Böylece çeşitli türdeki sıraları kabul ettiği toplam yönteminizi aşırı yüklenebilir.Standart yaklaşım her türü için aşırı oluşturmaktır.Başka bir yaklaşım, genel türde olması ve bir temsilci kullanarak belirli bir türe dönüştürmek aşırı oluşturmaktır.Her iki yaklaşım da birleştirebilirsiniz.

Cc981895.collapse_all(tr-tr,VS.110).gifAşırı her türü oluşturmak için

Desteklemek istediğiniz her türü için belirli bir aşırı oluşturabilirsiniz.Aşağıdaki kod örneği, aşırı gösterir Median yöntemi integer türü.

' 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
//int overload

public static double Median(this IEnumerable<int> source)
{
    return (from num in source select (double)num).Median();
}

Şimdi Ara Median her ikisi için de aşırı integer ve double , aşağıdaki kodda gösterildiği gibi türleri:

        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
        double[] numbers1 = { 1.9, 2, 8, 4, 5.7, 6, 7.2, 0 };

        var query1 = numbers1.Median();

        Console.WriteLine("double: Median = " + query1);



...


        int[] numbers2 = { 1, 2, 3, 4, 5 };

        var query2 = numbers2.Median();

        Console.WriteLine("int: Median = " + query2);



...


/*
 This code produces the following output:

 Double: Median = 4.85
 Integer: Median = 3
*/

Cc981895.collapse_all(tr-tr,VS.110).gifGenel tekrar yükleme oluşturmak için

Genel nesneler dizisi kabul eden aşırı de oluşturabilirsiniz.Bu aşırı bir temsilci parametre olarak alır ve bir dizi genel türdeki nesneleri belirli bir türe dönüştürmek için kullanır.

Aşağıdaki kod, aşırı gösterir Median götüren yöntemi Func<T, TResult> temsilci parametre olarak.Bu temsilci t genel türde bir nesne alıp türünde bir nesne döndüren 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
// Generic overload.

public static double Median<T>(this IEnumerable<T> numbers,
                       Func<T, double> selector)
{
    return (from num in numbers select selector(num)).Median();
}

Şimdi Ara Median herhangi bir türdeki nesnelerin bir dizi yöntemi.Kendi yöntemi aşırı tipi yoksa, temsilci parametre vardır.Visual Basic ve C# [NULL]'da, bu amaçla lambda ifade kullanabilirsiniz.Ayrıca, yalnızca, Visual Basic içinde kullanırsanız, Aggregate veya Group By yan tümcesi yöntem çağrısı yerine, iletebilir herhangi bir değer veya bu yan kapsamı içinde olan deyimi.

Aşağıdaki kod örneği nasıl çağırılacağını gösterir Median yöntemi dizisi ve bir dize dizisi.Dizeleri için ORTANCA dizisindeki dizelerin uzunlukları için hesaplanır.Nasıl örnek gösterir Func<T, TResult> parametresi için temsilci Median her servis talebi için yöntem.

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
int[] numbers3 = { 1, 2, 3, 4, 5 };

/* 
  You can use the num=>num lambda expression 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.          
*/

var query3 = numbers3.Median(num => num);

Console.WriteLine("int: Median = " + query3);

string[] numbers4 = { "one", "two", "three", "four", "five" };

// With the generic overload, you can also use numeric properties of objects.

var query4 = numbers4.Median(str => str.Length);

Console.WriteLine("String: Median = " + query4);

/*
 This code produces the following output:

 Integer: Median = 3
 String: Median = 4
*/

Bir koleksiyonu döndüren bir yöntem ekleme

Genişletebilmeniz için IEnumerable<T> arabirimi özel sorgu yöntemiyle bir değerler dizisini verir.Bu durumda, yöntem bir koleksiyon döndürmelidir IEnumerable<T>.Bu tür yöntemler filtreler veya veri dönüşümleri bir dizi değerleri uygulamak için kullanılabilir.

Aşağıdaki örnek adlı bir uzantısı yöntemi nasıl oluşturulacağını gösterir AlternateElements ilk öğesinden başlayarak, bir topluluk içindeki her öğenin dönen.

' Extension method for the IEnumerable(of T) interface. 
' The method returns every other element of a sequence.

<Extension()> 
Function AlternateElements(Of T)(
    ByVal source As IEnumerable(Of T)
    ) As IEnumerable(Of T)

    Dim list As New List(Of T)
    Dim i = 0
    For Each element In source
        If (i Mod 2 = 0) Then
            list.Add(element)
        End If
        i = i + 1
    Next
    Return list
End Function
// Extension method for the IEnumerable<T> interface. 
// The method returns every other element of a sequence.

public static IEnumerable<T> AlternateElements<T>(this IEnumerable<T> source)
{
    List<T> list = new List<T>();

    int i = 0;

    foreach (var element in source)
    {
        if (i % 2 == 0)
        {
            list.Add(element);
        }

        i++;
    }

    return list;
}

Yalnızca diğer yöntemleri çağırmak gibi herhangi bir sýralanabilir koleksiyon için bu uzantıyı yöntemini çağırabilirsiniz IEnumerable<T> arabirimi, aşağıdaki kodda gösterildiği gibi:

Dim strings() As String = {"a", "b", "c", "d", "e"}

Dim query = strings.AlternateElements()

For Each element In query
    Console.WriteLine(element)
Next

' This code produces the following output:
'
' a
' c
' e
string[] strings = { "a", "b", "c", "d", "e" };

var query = strings.AlternateElements();

foreach (var element in query)
{
    Console.WriteLine(element);
}
/*
 This code produces the following output:

 a
 c
 e
*/

Ayrıca bkz.

Başvuru

IEnumerable<T>

Uzantı yöntemleri (C# Programlama Kılavuzu)

Kavramlar

Uzantı yöntemleri (Visual Basic)