
(来自Linq in action)
举个例子实现:
查询以a开头的字符串,按降序输出。
C#代码:
var result = from word in list
where word.StartsWith("a")
orderby word descending
select word;
result.ToList().ForEach(str => Console.WriteLine(str));
// 输出:
// async
// apple
// amazon
// adobe
// acer
.OrderByDescending(str => { return str; });
这里 Where 和 OrderByDescending都是IEnumerable<T>的扩展方法,因为数组类型实现了该接口,所以可以直接调用这些这些扩展方法。
这些扩展方法的实现是在Enumerable类型中实现的,因此,更直接的是调用Enumerable类型的静态方法方法:
Enumerable.OrderByDescending(
Enumerable.Where(
list, str => str.StartsWith("a")), str => { return str; }
);
从这些逆向演化可以看出,查询语法就是一种"语法糖"。前面提到过,编译后运行时版本还是2.0,从这可以看出一些端倪。如果想继续深入了解该实现可以用ILDASM查看IL源代码和反射类库源代码。
result类型为IEnumerable<TElement>或派生自IEnumerable<TElement>接口的类型。
与 Linq 相关的程序集
System.Linq 命名空间在System.Core.dll中,接口类型及扩展方法的定义在该命名空间中,如:
Enumerable
IGrouping<TKey, TElement>
ILookup<TKey, TElement>
IQueryable<T>
IOrderedQueryable<T>
Expressions
...
System.Data.DataSetExtensions.dll 包含 Linq to DataSet 的相关类型的定义。
System.Data.Linq.dll 包含 Linq to SQL 的相关类型的定义。
System.Xml.Linq.dll 包含 Linq to XML 的相关类型的定义。
全程数据
为了下面介绍方便,构造以下,
数据结构图如下:
数据定义如下:
public class Student
{
public int StudentID { get; set; }
public string Name { get; set; }
override public string ToString()
{
return string.Format("Student ID:{0},Student Name:{1}", StudentID, Name);
}
}
public class Course
{
public int CourseID { get; set; }
public string CourseName { get; set; }
override public string ToString()
{
return string.Format("Course ID:{0},Course Name:{1}", CourseID, CourseName);
}
}
public class Score
{
public int StudentID { get; set; }
public int CourseID { get; set; }
public double Value { get; set; }
override public string ToString()
{
return string.Format("Student ID:{0},Course ID:{1},Score:{2}", StudentID, CourseID, Value);
}
}
public class DataSource
{
public static List<Student> Students { get; private set; }
public static List<Student> Students2 { get; private set; }
public static List<Score> Scores { get; private set; }
public static List<Course> Courses { get; private set; }
static DataSource()
{
Students = new List<Student>
{
new Student{ StudentID=1, Name="Andy" },
new Student{ StudentID=2, Name="Bill" },
new Student{ StudentID=3, Name="Cindy" },
new Student{ StudentID=4, Name="Dark" }
};
Students2 = new List<Student>
{
new Student{ StudentID=5, Name="Erik" },
new Student{ StudentID=6, Name="Frank" }
};
Courses = new List<Course>
{
new Course { CourseID = 1, CourseName = "C Language" },
new Course { CourseID = 2, CourseName = "Biophysics" },
new Course { CourseID = 3, CourseName = "Fundamentals of Compiling" },
new Course { CourseID = 4, CourseName = "Finance" },
new Course { CourseID = 5, CourseName = "College English" }
};
Scores = new List<Score>
{
new Score { StudentID = 1, CourseID = 1, Value = 78 },
new Score { StudentID = 1, CourseID = 2, Value = 60 },
new Score { StudentID = 1, CourseID = 3, Value = 92 },
new Score { StudentID = 1, CourseID = 4, Value = 85 },
new Score { StudentID = 1, CourseID = 5, Value = 55.5 },
new Score { StudentID = 2, CourseID = 1, Value = 59 },
new Score { StudentID = 2, CourseID = 2, Value = 78 },
new Score { StudentID = 2, CourseID = 3, Value = 86 },
new Score { StudentID = 3, CourseID = 2, Value = 60 },
new Score { StudentID = 4, CourseID = 4, Value = 96 },
new Score { StudentID = 5, CourseID = 5, Value = 78 }
};
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
· AI 智能体引爆开源社区「GitHub 热点速览」
· C#/.NET/.NET Core技术前沿周刊 | 第 29 期(2025年3.1-3.9)