Not
Bu sayfaya erişim yetkilendirme gerektiriyor. Oturum açmayı veya dizinleri değiştirmeyi deneyebilirsiniz.
Bu sayfaya erişim yetkilendirme gerektiriyor. Dizinleri değiştirmeyi deneyebilirsiniz.
Tüm LINQ tabanlı yöntemler iki benzer desenden birini izler. Numaralandırılabilir bir sıra alır. Farklı bir dizi veya tek bir değer döndürür. Şeklin tutarlılığı, benzer şekilde yöntemler yazarak LINQ'i genişletmenizi sağlar. Aslında LINQ ilk kez kullanıma sunulduğundan beri .NET kitaplıkları birçok .NET sürümünde yeni yöntemler kazanmıştır. Bu makalede, aynı deseni izleyen kendi yöntemlerinizi yazarak LINQ'yi genişletme örnekleri görürsünüz.
LINQ sorguları için özel yöntemler ekleme
Arabirime uzantı yöntemleri ekleyerek LINQ sorguları için kullandığınız yöntem IEnumerable<T> kümesini genişletin. Örneğin, standart ortalama veya maksimum işlemlere ek olarak, bir değer dizisinden tek bir değeri hesaplamak için özel bir toplama yöntemi oluşturursunuz. Ayrıca, bir değer dizisi için özel filtre veya belirli bir veri dönüşümü olarak çalışan ve yeni bir sıra döndüren bir yöntem de oluşturursunuz. Bu tür yöntemlere örnek olarak Distinct, Skipve Reverseverilebilir.
Arabirimi IEnumerable<T> genişlettiğinizde, kendi yöntemlerinizi herhangi bir numaralandırılabilir koleksiyona uygulayabilirsiniz. Daha fazla bilgi için bkz . Uzantı üyeleri.
Toplama yöntemi, bir değer kümesinden tek bir değer hesaplar. LINQ Average, Min, ve Max gibi çeşitli toplama yöntemleri sağlar. IEnumerable<T> arayüzüne bir uzantı yöntemi ekleyerek kendi toplama yöntemizi oluşturun.
C# 14'te başlayarak, birden çok uzantı üyesi içerecek bir uzantı bloğu bildirebilirsiniz. Anahtar sözcüğünü extension ve ardından parantez içinde alıcı parametresini içeren bir uzantı bloğu bildirin. Aşağıdaki kod örneği, uzantı bloğunda adlı Median bir uzantı yönteminin nasıl oluşturulacağını gösterir. yöntemi, türünde doublebir sayı dizisi için ortanca değeri hesaplar.
extension(IEnumerable<double>? source)
{
public double Median()
{
if (source is null || !source.Any())
{
throw new InvalidOperationException("Cannot compute median for a null or empty set.");
}
var sortedList =
source.OrderBy(number => number).ToList();
int itemIndex = sortedList.Count / 2;
if (sortedList.Count % 2 == 0)
{
// Even number of items.
return (sortedList[itemIndex] + sortedList[itemIndex - 1]) / 2;
}
else
{
// Odd number of items.
return sortedList[itemIndex];
}
}
}
Uzantı yöntemini bildirmek için değiştiriciyi thisstatik yönteme de ekleyebilirsiniz. Aşağıdaki kod eşdeğer Median uzantı yöntemini gösterir:
public static class EnumerableExtension
{
public static double Median(this IEnumerable<double>? source)
{
if (source is null || !source.Any())
{
throw new InvalidOperationException("Cannot compute median for a null or empty set.");
}
var sortedList =
source.OrderBy(number => number).ToList();
int itemIndex = sortedList.Count / 2;
if (sortedList.Count % 2 == 0)
{
// Even number of items.
return (sortedList[itemIndex] + sortedList[itemIndex - 1]) / 2;
}
else
{
// Odd number of items.
return sortedList[itemIndex];
}
}
}
Herhangi bir numaralandırılabilir koleksiyon için her iki uzantı yöntemini de arabirimden diğer toplama yöntemlerini çağırdığınız gibi çağırın IEnumerable<T> .
Aşağıdaki kod örneği, Median türünde bir dizi için double yönteminin nasıl kullanılacağını gösterir.
double[] numbers = [1.9, 2, 8, 4, 5.7, 6, 7.2, 0];
var query = numbers.Median();
Console.WriteLine($"double: Median = {query}");
// This code produces the following output:
// double: Median = 4.85
Çeşitli türlerdeki dizileri kabul etmek için toplama yönteminizi aşırı yükleyin. Standart yaklaşım, her tür için bir aşırı yükleme oluşturmaktır. Bir diğer yaklaşım da genel bir tür alan ve temsilci kullanarak bunu belirli bir türe dönüştüren bir aşırı yükleme oluşturmaktır. Ayrıca her iki yaklaşımı da birleştirebilirsiniz.
Desteklemek istediğiniz her tür için belirli bir aşırı yükleme oluşturun. Aşağıdaki kod örneği, Median türü için int yönteminin aşırı yüklemesini gösterir.
// int overload
public static double Median(this IEnumerable<int> source) =>
(from number in source select (double)number).Median();
Artık aşağıdaki kodda gösterildiği gibi, hem Median hem de integer türleri için double aşırı yüklemelerini çağırabilirsiniz.
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
// int: Median = 3
Ayrıca , genel bir nesne dizisini kabul eden bir aşırı yükleme de oluşturabilirsiniz. Bu aşırı yükleme bir temsilciyi parametre olarak alır ve bunu kullanarak genel türdeki nesnelerin sırasını belirli bir türe dönüştürür.
Aşağıdaki kod, Median temsilcisini parametre olarak alan Func<T,TResult> yönteminin aşırı yüklemesini gösterir. Bu temsilci T genel türünde bir nesne alır ve türünde double bir nesne döndürür.
// generic overload
public static double Median<T>(
this IEnumerable<T> numbers, Func<T, double> selector) =>
(from num in numbers select selector(num)).Median();
Artık herhangi bir türdeki Median nesne dizisi için yöntemini çağırabilirsiniz. Türün kendi yöntem aşırı yüklemesi yoksa, bir delege parametresi geçirin. C# dilinde, bu amaçla bir lambda ifadesi kullanabilirsiniz. Ayrıca, yalnızca Visual Basic'te, yöntem çağrısı yerine Aggregate veya Group By yan tümcesini kullanırsanız, bu yan tümce kapsamındaki herhangi bir değeri veya ifadeyi iletebilirsiniz.
Aşağıdaki örnek kod, bir tamsayı dizisi ve bir dize dizisi için Median yönteminin nasıl çağrılacağını gösterir. Dizeler için, dizideki dizelerin uzunlukları için ortanca değer hesaplanır. Örnek, her durum için temsilci parametresinin Func<T,TResult> yöntemine Median nasıl geçirileceğini göstermektedir.
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:
// int: Median = 3
// string: Median = 4
Arabirimi, IEnumerable<T>bir değer dizisi döndüren özel bir sorgu yöntemiyle genişletin. Bu durumda, yöntem türünde IEnumerable<T> bir koleksiyon döndürmelidir. Bu tür yöntemler, bir değer dizisine filtre veya veri dönüşümleri uygulamak için kullanılabilir.
Aşağıdaki örnekte, ilk öğeden başlayarak koleksiyondaki diğer tüm öğeleri döndüren adlı AlternateElements bir uzantı yönteminin nasıl oluşturulacağı gösterilmektedir.
// 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)
{
int index = 0;
foreach (T element in source)
{
if (index % 2 == 0)
{
yield return element;
}
index++;
}
}
Aşağıdaki kodda gösterildiği gibi, arabirimden IEnumerable<T> diğer yöntemleri çağırdığınız gibi, numaralandırılabilir herhangi bir koleksiyon için bu uzantı yöntemini çağırın:
string[] strings = ["a", "b", "c", "d", "e"];
var query5 = strings.AlternateElements();
foreach (var element in query5)
{
Console.WriteLine(element);
}
// This code produces the following output:
// a
// c
// e
Bu makalede gösterilen her örnek farklı bir alıcıya sahiptir. Bu, her yöntemi benzersiz alıcıyı belirten farklı bir uzantı bloğunda bildirmeniz gerektiği anlamına gelir. Aşağıdaki kod örneği, her biri bu makalede tanımlanan yöntemlerden birini içeren üç farklı uzantı bloğuna sahip tek bir statik sınıfı gösterir:
public static class EnumerableExtension
{
extension(IEnumerable<double>? source)
{
public double Median()
{
if (source is null || !source.Any())
{
throw new InvalidOperationException("Cannot compute median for a null or empty set.");
}
var sortedList =
source.OrderBy(number => number).ToList();
int itemIndex = sortedList.Count / 2;
if (sortedList.Count % 2 == 0)
{
// Even number of items.
return (sortedList[itemIndex] + sortedList[itemIndex - 1]) / 2;
}
else
{
// Odd number of items.
return sortedList[itemIndex];
}
}
}
extension(IEnumerable<int> source)
{
public double Median() =>
(from number in source select (double)number).Median();
}
extension<T>(IEnumerable<T> source)
{
public double Median(Func<T, double> selector) =>
(from num in source select selector(num)).Median();
public IEnumerable<T> AlternateElements()
{
int index = 0;
foreach (T element in source)
{
if (index % 2 == 0)
{
yield return element;
}
index++;
}
}
}
}
Son uzantı bloğu genel bir uzantı bloğu bildirir. Alıcının tür parametresi doğrudan extension üzerinde bildirilir.
Yukarıdaki örnek, her uzantı bloğunda bir uzantı üyesi bildirir. Çoğu durumda, aynı alıcı için birden çok uzantı üyesi oluşturursunuz. Bu gibi durumlarda, bu üyeler için uzantıları tek bir uzantı bloğunda bildirin.