日期:2014-06-10  浏览次数:20514 次

本篇简单回顾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 { getset; } 
    public int Age { getset; } 
    public string Phone { getset; } 
}

初始化集合:
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的内容将在下面的内容一步一步展开。