如果要扩展LINQ查询方法集,只需要为IEnumerable扩展方法。
第一种:扩展聚合方法,类似已有python基础教程的Max、Min,可以给具体类型扩展,也可以给泛型扩展。
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Linq;
namespace ConsoleApp4
{
class Program
{
static void Main(string[] args)
{
var numbers1 = new double[]{ 1.9, 2, 8, 4, 5.7, 6, 7.2, 0 };
var query1 = numbers1.Median();
Console.WriteLine("double: Median = " + query1);
var numbers2 = new int[] { 4, 5, 6, 8, 0 };
var query2 = numbers2.Median();
Console.WriteLine($"int:Median ={query2}");
var str1 = new string[] { "ab", "abc", "abcde", "abcedfs" }; ;
var query3 = str1.Median(x => x.Length);
Console.WriteLine($"string:{query3}");
}
}
public static class LINQExtension
{
public static double Median(this IEnumerable<double> source)
{
if(source.Count()==0)
{
throw new InvalidOperationException("无法计算中位数");
}
var sortedList = source.OrderBy(x => x);
int itemIndex = (int)sortedList.Count()/2;
// 索引从0开始,itemIndex总是偏大
if(sortedList.Count()%2==0)
{
return (sortedList.ElementAt(itemIndex) + sortedList.ElementAt(itemIndex - 1)) / 2;
}
else
{
return sortedList.ElementAt(itemIndex);
}
}
//Int类型重载求中位数
public static double Median(this IEnumerable<int> source)
{
return source.Select(x => Convert.ToDouble(x)).Median();
}
//泛型,需传入选择器
public static double Median<T>(this IEnumerable<T> source,Func<T,double> selector)
{
return source.Select(x => selector(x)).Median();
}
}
}
第二中:扩展返回集合的方法,类似Where、Orderby
public static class LINQExtension
{
public static IEnumerable<T> AlternateElements<T>(this IEnumerable<T> source)
{
List<T> list = new List<T>();
int i = 0;
foreach (var item in source)
{
if (i % 4 == 2)
{
list.Add(item);
}
}
return list;
}
}
量变会引c#教程起质变。