为了理解为什么我们应该使用LINQ,让我们看一些示例。假设您要从一系列Student对象中查找青少年学生的列表。
在C#2.0之前,我们必须使用“ foreach”或“ for”循环遍历集合以查找特定对象。例如,我们必须编写以下代码,以从年龄在12至20岁(青少年13至19岁)的一系列学生中查找所有学生对象:
示例:在C#1.0中,使用for循环从集合中查找元素
class Student
{
public int StudentID { get; set; }
public String StudentName { get; set; }
public int Age { get; set; }
}
class Program
{
static void Main(string[] args)
{
Student[] studentArray = {
new Student() { StudentID = 1, StudentName = "John", Age = 18 },
new Student() { StudentID = 2, StudentName = "Steve", Age = 21 },
new Student() { StudentID = 3, StudentName = "Bill", Age = 25 },
new Student() { StudentID = 4, StudentName = "Ram" , Age = 20 },
new Student() { StudentID = 5, StudentName = "Ron" , Age = 31 },
new Student() { StudentID = 6, StudentName = "Chris", Age = 17 },
new Student() { StudentID = 7, StudentName = "Rob",Age = 19 },
};
Student[] students = new Student[10];
int i = 0;
foreach (Student std in studentArray)
{
if (std.Age > 12 && std.Age < 20)
{
students[i] = std;
i++;
}
}
}
}
for循环的使用很麻烦,不可维护和可读性差。C#2.0引入了委托,可以用来处理这种情况,如下所示。
示例:使用委托从C#2.0中的集合中查找元素
delegate bool FindStudent(Student std);
class StudentExtension
{
public static Student[] where(Student[] stdArray, FindStudent del)
{
int i=0;
Student[] result = new Student[10];
foreach (Student std in stdArray)
if (del(std))
{
result[i] = std;
i++;
}
return result;
}
}
class Program
{
static void Main(string[] args)
{
Student[] studentArray = {
new Student() { StudentID = 1, StudentName = "John", Age = 18 } ,
new Student() { StudentID = 2, StudentName = "Steve", Age = 21 } ,
new Student() { StudentID = 3, StudentName = "Bill", Age = 25 } ,
new Student() { StudentID = 4, StudentName = "Ram" , Age = 20 } ,
new Student() { StudentID = 5, StudentName = "Ron" , Age = 31 } ,
new Student() { StudentID = 6, StudentName = "Chris", Age = 17 } ,
new Student() { StudentID = 7, StudentName = "Rob",Age = 19 } ,
};
Student[] students = StudentExtension.where(studentArray, delegate(Student std){
return std.Age > 12 && std.Age < 20;
});
}
}
}
因此,使用C#2.0,您可以利用委托的优势找到符合任何条件的学生。你不必使用for循环来查找使用不同标准的学生。例如,可以使用相同的委托函数查找StudentId为5或姓名为Bill的学生,如下所示:
Student[] students = StudentExtension.where(studentArray, delegate(Student std) {
return std.StudentID == 5;
});
//此外,请使用同一委托使用其他条件
Student[] students = StudentExtension.where(studentArray, delegate(Student std) {
return std.StudentName == "Bill";
});
C#团队认为他们仍然需要使代码更加紧凑和易读。 因此,他们在C#3.0中引入了扩展方法,lambda表达式,表达式树,匿名类型和查询表达式。 您可以使用C#3.0的这些功能(它们是LINQ的构建块)来查询不同类型的集合并在单个语句中获取结果元素。
下面的示例演示如何使用带有 lambda 表达式的 LINQ 查询从 student 集合中查找特定的学生。
示例:LINQ
class Program
{ static void Main(string[] args)
{
Student[] studentArray = {
new Student() { StudentID = 1, StudentName = "John", age = 18 } ,
new Student() { StudentID = 2, StudentName = "Steve", age = 21 } ,
new Student() { StudentID = 3, StudentName = "Bill", age = 25 } ,
new Student() { StudentID = 4, StudentName = "Ram" , age = 20 } ,
new Student() { StudentID = 5, StudentName = "Ron" , age = 31 } ,
new Student() { StudentID = 6, StudentName = "Chris", age = 17 } ,
new Student() { StudentID = 7, StudentName = "Rob",age = 19 } ,
};
// 使用LINQ查找青少年学生
Student[] teenAgerStudents = studentArray.Where(s => s.age > 12 && s.age < 20).ToArray();
// 使用LINQ查找名字为Bill的第一位学生
Student bill = studentArray.Where(s => s.StudentName == "Bill").FirstOrDefault();
// 使用LINQ查找StudentID为5的学生
Student student5 = studentArray.Where(s => s.StudentID == 5).FirstOrDefault();
}
}
如上例所示,我们在单个语句中使用LINQ运算符和lambda表达式指定了不同的条件。因此,LINQ使代码更紧凑和可读性强,并且还可以用于查询不同的数据源。例如,如果您在数据库中有一个学生表,而不是上面的学生对象数组,则仍可以使用相同的查询使用实体框架查找学生。
LINQ的优势
Familiar language(熟悉的语言): 开发人员不必为每种类型的数据源或数据格式学习新的查询语言。
Less coding(更少的代码): 与更传统的方法相比,它减少了要编写的代码量。
Readable code(代码可读性): LINQ使代码更具可读性,因此其他开发人员可以轻松地理解和维护它。
Standardized way of querying multiple data sources(查询多个数据源的标准化方法): 相同的LINQ语法可用于查询多个数据源。
Compile time safety of queries(查询的编译时安全性): 它在编译时提供对象的类型检查。
IntelliSense Support(智能感知支持): LINQ为通用集合提供了IntelliSense。
Shaping data(数据形状): 您可以以不同形状检索数据。