اضافه کردن متد به LINQ
بسم الله الرحمن الرحیم
می خواهیم به تمامی لیست هایی که از نوع double ایجاد می شوند یک متد برای پیدا کردن عنصر میانی آنها بنویسیم
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)
{
//
بسم الله الرحمن الرحیم
می خواهیم به تمامی لیست هایی که از نوع double ایجاد می شوند یک متد برای پیدا کردن عنصر میانی آنها بنویسیم
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);
}
}
}
برای استفاده از این متد کافی است که یک لیست از double ایجاد کنیم و به صورت زیر تابع خود را صدا بزنیم:
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
*/
حال می توانیم این متد را برای نوع های دیگری چون int نیز بازنویسی کنیم:
//int overload
public static double Median(this IEnumerable<int> source)
{
return (from num in source select (double)num).Median();
}
حال می توانیم متد خود را برای نوع های int و double استفاده کنیم
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
*/
شما همچنین می توانید برای نوع های Generic این متد را overload کنید. این Overload یک Delegate به عنوان پارارمتر ایجاد می کند و تا بخ وسیله آن یک مجموعه یا لیست Generic را به یک نوع مشخص تبدیل کند.
متد زیر نشان می دهد که ما چطور یک Func<T, TResult> را به عنوان پارامتر ایجاد کرده ایم، این Delegate یک شی از نوع Generic T ایجاد می کند و یک نوع double بر می گرداند.
// Generic overload.
public static double Median<T>(this IEnumerable<T> numbers,
Func<T, double> selector)
{
return (from num in numbers select selector(num)).Median();
}
در این مثال شما متوجه شدید که چطور می توانیم یک متد LINQ بنویسیم تا در تمامی نوع هایی که کاربر از آن شی ایی ایجاد می کند، متد خود را استفاده کنیم.
نحوه استفاده از متد:
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
*/
اگر بخواهیم برای متد خود یک مجموعه یا لیست را به عنوان خروجی متد تعیین کنیم، می بایست به صورت زیر متد خود را با استفاده از اینترفیس IEnumerable<T> ایجاد کنیم
// 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;
}
فراخوانی متد
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
*/