官方定义,Linq是语言集成查询 (LINQ) 是一系列直接将查询功能集成到 C# 语言的技术统称。可以认为Linq就是使用Lambda表达式完成类似SQL语法的功能,sum、count、avg、排序、分组、分页等等,某些方面更强大,使用便捷
自己写一个实现方法,方便我们更好的理解使用Linq。
先声明一个匿名对象集合,后面有非匿名的,匿名对象是C#很好用的一个特性,
var students = Enumerable.Range(1, 10).Select(i => new
{
ID = i,
Name = i>7? "hello" : $"hello{i}",
Age = i < 5 ? 16 : i + 10
});
/*输出结果如下
{ ID = 1, Name = hello1, Age = 16 }
{ ID = 2, Name = hello2, Age = 16 }
{ ID = 3, Name = hello3, Age = 16 }
{ ID = 4, Name = hello4, Age = 16 }
{ ID = 5, Name = hello5, Age = 15 }
{ ID = 6, Name = hello6, Age = 16 }
{ ID = 7, Name = hello7, Age = 17 }
{ ID = 8, Name = hello, Age = 18 }
{ ID = 9, Name = hello, Age = 19 }
{ ID = 10, Name = hello, Age = 20 }
*/
Enumerable.Range(1, 10) 生成一个1到10的整数序列;
Select 再Linq里面是一个投影操作,可以理解成sql 里面的 select;
Count 用法
var count1 = students.Where(p => p.Name == "hello").Count();
var count2 = students.Count(p=>p.Name== "hello");
Console.WriteLine(count1);//3
Console.WriteLine(count2);//3
简单写一个自定义的Count 方法
var count1 = students.Where(p => p.Name == "hello" && p.Age > 18).Count();
var count2 = students.MyCount(p=>p.Name== "hello"&& p.Age>18);
Console.WriteLine(count1);//2
Console.WriteLine(count2);//2
static class A
{
public static int MyCount<T>(this IEnumerable<T> source, Func<T, bool> func)
{
int i = 0;
foreach (var item in source)
{
if (func(item))
{
i++;
}
}
return i;
}
}
实现的自定义Linq方法的原理,首先这次不使用匿名对象了,不容易理解,先看代码,其实就是匿名函数和委托
var students = Enumerable.Range(1, 10).Select(i => new Student
{
ID = i,
Name = i > 7 ? "hello" : $"hello{i}",
Age = i < 5 ? 16 : i + 10
});
//p=>p.Name== "hello"&& p.Age>18 其实是匿名函数 等价于
Func<Student,bool> fun = p => p.Name == "hello" && p.Age > 18;
//等价于
fun = p =>
{
return p.Name == "hello" && p.Age > 18;
};
//等价于
fun =delegate(Student p)
{
return p.Name == "hello" && p.Age > 18;
};
//调用
var result1= fun(new Student { Name= "hello", Age=19 });
Console.WriteLine(result1); //True
var result2 = fun(new Student { Name = "hello1", Age = 18 });
Console.WriteLine(result2);//False
var count2 = students.MyCount(p=>p.Name== "hello"&& p.Age>18);
Console.WriteLine(count2);//2
static class A
{
public static int MyCount<T>(this IEnumerable<T> source, Func<T, bool> func)
{
int i = 0;
foreach (var item in source)
{
if (func(item))
{
i++;
}
}
return i;
}
}
class Student
{
public int ID { get; set; }
public string Name { get; set; }
public int Age { get; set; }
}
students.MyCount(p=>p.Name== "hello"&& p.Age>18);
p=>p.Name== "hello"&& p.Age>18 是一个返回bool类型的匿名函数,相当于
Func<Student,bool> fun = p => p.Name == "hello" && p.Age > 18;
这样就可以实现想要的效果了。代码里面有详细的一步步反向延展。
Linq如何使用(一)委托Delegate - 简书 (jianshu.com)
Linq如何使用(二)Lambda 声明委托Delegate - 简书 (jianshu.com)
Linq如何使用(四)-哪些地方用,如何用 - 简书 (jianshu.com)