本篇简单回顾C#语言集合操作的变化,通过与Linq对等的面向对象的语法来认识Linq。
Linq是Language
Integrated Query, 初识Linq感觉跟SQL
Server的Tsql很像,可以进行语言必备的逻辑操作,也可以实现对集合的直接查询。
Net1.X时代
C#不支持泛型,集合用元素只能为object类型的ArrayList等。
添加、取出元素都与Object类型进行强制类型转换,
如果是值类型要进行装箱操作,取出元素时进行拆箱操作,影响效率,
编译时不进行类型检查,类型不匹配运行时可能出错。
定义实体类:
public class Employee
{
private string _Name;
private int _Age;
private string _Phone;
public string Name
{
get { return _Name;
}
set {
_Name = value;
}
}
public int Age
{
get { return _Age;
}
set {
_Age = value;
}
}
public string Phone
{
get { return _Phone;
}
set {
_Phone = value;
}
}
public Employee(string name, int age, string phone)
{
_Name = name;
_Age = age;
_Phone = phone;
}
}
初识化集合:
这进行类型转换。
ArrayList
list;
list = new ArrayList();
list.Add(new Employee("Zxjay", 20, "010-123456"));
list.Add(new Employee("Andy", 30, "020-123456"));
list.Add(new Employee("Bill", 50, "010-3456789"));
list.Add(new Employee("Lee", 40, "0532-234567"));
排序:
需实现IComparer接口。
class SortArrayList :
IComparer
{
public int Compare(object x, object y)
{
Employee
a = x as Employee;
Employee
b = y as Employee;
return a.Name.CompareTo(b.Name);
}
}
list.Sort(new SortArrayList());
遍历每个元素取得符合条件的元素放到新的集合:
这里也进行类型转换。
ArrayList
selectedList = new ArrayList();
foreach (object obj in list)
{
Employee
emp = obj as Employee;
if (emp != null && emp.Phone.StartsWith("010") && emp.Age < 50)
{
selectedList.Add(emp);
}
}
输出集合元素:
这里也进行类型转换。
private void ShowList(ArrayList
list)
{
Console.WriteLine("{0,-20:G}{1,-5:G}{2}", "Name", "Age", "Phone");
foreach (object obj in list)
{
Employee
emp = obj as Employee;
if (emp != null)
{
Console.WriteLine("{0,-20:G}{1,-5:G}{2}",
emp.Name, emp.Age,
emp.Phone);
}
}
}
.NET
2.0时代
加入了泛型和匿名方法,代码量减少,逻辑清晰了许多,编译期间强类型检查和去掉了强制类型转换及装箱、拆箱操作。
定义实体类跟.NET
1.1时代一样。
排序选择直接用匿名方法实现:
list.Sort(
delegate(Employee
x, Employee
y)
{
return x.Name.CompareTo(y.Name);
}
);
List<Employee> listBeijing = list.FindAll(
delegate(Employee
emp)
{
return emp.Phone.StartsWith("010") && emp.Age < 50;
}
);
输出集合元素:
这里去掉了强制类型转换。
private void ShowList(IList<Employee> list)
{
Console.WriteLine("{0,-20:G}{1,-5:G}{2}", "Name", "Age", "Phone");
foreach (Employee
emp in list)
{
Console.WriteLine("{0,-20:G}{1,-5:G}{2}",
emp.Name, emp.Age,
emp.Phone);
}
}
.Net
3.X时代
自动属性、扩展方法、隐含类型、匿名类型、类型集合初识化器、Lambda表达式,有大大简化了编程复杂度。
定义实体类:
用自动属性。
public class Employee
{
public string Name
{ get; set;
}
public int Age
{ get; set;
}
public string Phone
{ get; set; }
}
初始化集合:
list = new List<Employee>
{
new Employee{
Name = "Zxjay",
Age = 20,
Phone = "010-123456" },
new Employee{
Name = "Andy",
Age = 30,
Phone = "020-123456" },
new Employee{
Name = "Bill",
Age = 50,
Phone = "010-345678" },
new Employee{
Name = "Lee",
Age = 40,
Phone = "010-234567" }
};
排序选择:
用Lambda表达式实现:
list.Sort((Employee x, Employee
y) => { return x.Name.CompareTo(y.Name);
});
var listBijing = list.FindAll(
(Employee
emp) => { return emp.Phone.StartsWith("010") && emp.Age < 50;
});
输出集合元素:
用扩展方法。
private void ShowList(List<Employee> list)
{
Console.WriteLine("{0,-20:G}{1,-5:G}{2}", "Name", "Age", "Phone");
list.ForEach((Employee
emp) => Console.WriteLine("{0,-20:G}{1,-5:G}{2}",
emp.Name, emp.Age, emp.Phone));
}
这些查询大大简化,但这些还是面向对象的方法。
Linq这样实现排序选择等操作:
var selectResult = from emp in list
where emp.Phone.StartsWith("010") && emp.Age < 50
orderby emp.Name
select emp;
这才是真正意义上的语言集成查询,是不是似曾相识?跟SQL语句相似,只是把select字句放在最后。
本篇仅仅是对Linq的概述及语言内集合查询机制的变化的概要介绍,Linq的内容将在下面的内容一步一步展开。