LINQ学习之旅——第一站"LTO"之非延时标准查询操作符(上)

  前两节已经介绍了Linq To Object中的延时标准查询操作符,同样的,接下来我也将分两节内容来讲解非延时标准操作符,这些操作符一般是用来辅助延时标准查询操作符的使用。(注:下面操作符的示例中Employee类(雇员类)和Salary类(薪水类)的定义请参考上一节内容)

  1.ToArray操作符

  (1)作用:用于将输入序列转换成一个数组;

  (2)方法原型

    public static T[] ToArray<T>(

    this IEnumerable<T> source);

  (3)原型说明:操作符ToArray接受一个包含元素类型为T的输入序列source,生成一个元素类型为T的数组并返回;

  (4)示例验证

ToArray操作符
 1 staticvoid Main(string[] args)
2 {
3 //定义雇员数组
4 Employee[] employees =new Employee[]
5 {
6 new Employee{Id="0001",Name="张三",Age=32},
7 new Employee{Id="0002",Name="李四",Age=31},
8 new Employee{Id="0003",Name="王五",Age=32},
9 new Employee{Id="0004",Name="小六",Age=25},
10 new Employee{Id="0005",Name="张麻子",Age=40},
11 new Employee{Id="0006",Name="王小二",Age=25},
12 new Employee{Id="0007",Name="灭绝师太",Age=55},
13 };
14
15 Console.WriteLine("调用ToArray操作符:");
16 Console.WriteLine("------------------------------------");
17
18 Employee[] employees1 = employees.Where(e => e.Age ==25).ToArray();
19
20 Console.WriteLine("年龄为25的雇员:");
21 foreach (var e in employees1)
22 {
23 Console.WriteLine(e);
24 }
25
26 Console.Read();
27 }

结果

  2.ToList操作符

  (1)作用:用于将一个输入序列转换成一个类型为List<T>集合对象;

  (2)方法原型

    public static List<T> ToList<T>(

    this IEnumerable<T> source);

  (3)原型说明:ToList操作符接受一个元素类型为T的输入序列,生成一个元素类型为T的List序列并返回。其中返回值List<T>是一个可以通过索引访问的强类型列表,它也是C#2.0中比较常用的集合类型之一;

  (4)示例验证

ToList操作符
 1 staticvoid Main(string[] args)
2 {
3 //定义雇员数组
4 Employee[] employees =new Employee[]
5 {
6 new Employee{Id="0001",Name="张三",Age=32},
7 new Employee{Id="0002",Name="李四",Age=31},
8 new Employee{Id="0003",Name="王五",Age=32},
9 new Employee{Id="0004",Name="小六",Age=25},
10 new Employee{Id="0005",Name="张麻子",Age=40},
11 new Employee{Id="0006",Name="王小二",Age=25},
12 new Employee{Id="0007",Name="灭绝师太",Age=55},
13 };
14
15 Console.WriteLine("调用ToList操作符:");
16 Console.WriteLine("------------------------------------");
17
18 List<Employee> employeelist = employees.Where(e => e.Age >30).ToList();
19
20 Console.WriteLine("年龄大于30的雇员:");
21 foreach (var e in employeelist)
22 {
23 Console.WriteLine(e);
24 }
25
26 Console.Read();
27 }

结果

  3.ToDictionary操作符

  (1)作用:用于将一个输入序列转换成一个类型为Dictionary<K,T>的集合对象;

  (2)方法原型

    ①原型定义:

    public static Dictionary<K,T>  ToDictionary<T,K>(

    this IEnumerable<T> source,

    Func<T,K> keySelector);

    ②原型定义:

    public static Dictionary<K,T> ToDictionary<T,K>(

    this IEnumerable<T> source,

    Func<T,K> keySelector,

    IEqualityComparer<K> comparer);

    ③原型定义:

    public static Dictionary<K,E> ToDictionary<T,K,E>(

    this IEnumerable<T> source,

    Func<T,K> keySelector,

    Func<T,E> elementSelector);

    ④原型定义:

    public static Dictionary<K,E> ToDictionary<T,K,E>(

    this IEnumerable<T> source,

    Func<T,K> keySelector,

    Func<T,E> elementSelector,

    IEqualityComparer<K> comparer);

  (3)原型说明:操作符ToDictionary的第一种方法原型接收一个输入序列source和一个方法委托参数keySelector,返回一个Dictionary<K,T>类型的集合。其中Dictionary<K,T>表示一种键和值的集合,它允许键和对应于键的值存储在集合内部,且每个键必须唯一。并且一个键只能对应一个值,可以通过访问键来查询值。在调用操作符ToDictionary时,系统把输入序列中每一个类型为T的元素传递给委托keySelector,委托根据输入的参数生成一个类型为K的key对象,并将该对象key和与其对应的元素T组成一组键和值添加到返回序列中。第二中方法原型相比于第一种,多了一个类型为IEqualityComparer<K>的参数,用于对象的比较。因为在Dictionary<K,T>集合中键必须唯一,所以一定会对委托keySelector产生的键进行一一对比,而在第一种方法原型里,采用的是默认相等比较器EqualityComparer<T>.Default来进行键的比较,但对于第二种方法原型则允许开发人员自定义比较逻辑,因此相比较而言,第二种显得更加灵活。

  第三种方法原型比第一种多了一个委托参数elementSelector,用于将输入序列中类型为T的元素转换成类型为E的对象,将该对象和委托keySelector产生的类型为K的键对象key组成一组键与值添加到结果序列中,所以第三种方法原型最后的返回值为Dictionary<K,E>。而最后一种方法原型的实现效果其实就是第二、三种方法原型的合并效果。看了对操作符ToDictionary原型分析,你是否会感觉到其实操作符ToDictionary原型和之前讲到过的GroupBy操作符在有着相似之处;

  (4)示例验证

①自定义雇员姓名比较类

雇员名字比较类
 1 //雇员名字比较类
2 publicclass EmployeeNameComparer:IEqualityComparer<string>
3 {
4 publicbool Equals(string name1, string name2)
5 {
6 return name1 == name2;
7 }
8
9 publicint GetHashCode(string name)
10 {
11 return name.GetHashCode();
12 }
13 }

②调用ToDictionary操作符

ToDictionary操作符
 1 staticvoid Main(string[] args)
2 {
3 //定义雇员数组
4 Employee[] employees =new Employee[]
5 {
6 new Employee{Id="0001",Name="张三",Age=32},
7 new Employee{Id="0002",Name="李四",Age=31},
8 new Employee{Id="0003",Name="王五",Age=32},
9 new Employee{Id="0004",Name="小六",Age=25},
10 new Employee{Id="0005",Name="张麻子",Age=40},
11 new Employee{Id="0006",Name="王小二",Age=25},
12 new Employee{Id="0007",Name="灭绝师太",Age=55},
13 };
14
15 //ToDictionary第一个原型
16 Console.WriteLine("调用ToDictionary操作符第一个方法原型:");
17 Console.WriteLine("------------------------------------");
18
19 Dictionary<string,Employee> employeedictionary= employees.ToDictionary(e=>e.Id);
20
21 Console.WriteLine("0001号雇员:");
22 Employee employee = employeedictionary["0001"];
23 Console.WriteLine(employee.ToString());
24
25 Console.WriteLine("***************************************************");
26
27 //ToDictionary第二个原型
28 Console.WriteLine("调用ToDictionary操作符第二个方法原型:");
29 Console.WriteLine("------------------------------------");
30
31 //生成一个雇员名字比较类的辅助对象
32 EmployeeNameComparer enc =new EmployeeNameComparer();
33
34 Dictionary<string, Employee> employeedictionary1 = employees.ToDictionary(e => e.Name,enc);
35
36 Console.WriteLine("姓名为张麻子的雇员:");
37 Employee employee1 = employeedictionary1["张麻子"];
38 Console.WriteLine(employee1.ToString());
39
40 Console.WriteLine("***************************************************");
41
42 //ToDictionary第三个原型
43 Console.WriteLine("调用ToDictionary操作符第三个方法原型:");
44 Console.WriteLine("------------------------------------");
45
46 Dictionary<string, string> employeedictionary2 = employees.ToDictionary(e => e.Id, e =>e.Name);
47
48 Console.WriteLine("0004号雇员(姓名):");
49 string employeename = employeedictionary2["0004"];
50 Console.WriteLine(employeename);
51
52 Console.WriteLine("***************************************************");
53
54 //ToDictionary第四个原型
55 Console.WriteLine("调用ToDictionary操作符第四个方法原型:");
56 Console.WriteLine("------------------------------------");
57
58 //生成一个雇员名字比较类的辅助对象
59 EmployeeNameComparer enc1 =new EmployeeNameComparer();
60
61 Dictionary<string, string> employeedictionary3 = employees.ToDictionary(e => e.Name, e => e.Id, enc1);
62
63 Console.WriteLine("姓名为张麻子的雇员(编号):");
64 string employeeid = employeedictionary3["张麻子"];
65 Console.WriteLine(employeeid);
66
67 Console.Read();
68
69 }

③结果

  4.ToLookup操作符

  (1)作用:用于将一个输入序列转换成一个类型ILookup<K,T>的集合对象;

  (2)方法原型

    ①原型定义:

    public static ILookup<K,T> ToLookup<T,K>(

    this IEnumerable<T> source,

    Func<T,K> keySelector);

    ②原型定义:

    public static ILookup<K,T> ToLookup<T,K>(

    this IEnumerable<T> source,

    Func<T,K> keySelector,

    IEqualityComparer<K> comparer);

    ③原型定义:

    public static ILookup<K,E> ToLookup<T,K,E>(

    this IEnumerable<T> source,

    Func<T,K> keySelector,

    Func<T,E> elementSelector);

    ④原型定义:

    public static ILookup<K,E> ToLookup<T,K,E>(

    this IEnumerable<T> source,

    Func<T,K> keySelector,

    Func<T,E> elementSelector,

    IEqualityComparer<K> comparer);

  (3)原型说明:操作符ToLookup的方法原型和ToDictionary操作符一样,但其方法的实现有所不同,它们的不同是由返回的集合类型之间有差别造成的,操作符ToDiictionary返回的类型集合Dictionary<K,T>中的一个键只能对应一个元素值,而对于操作符ToLookup返回的类型集合ILookup<K,T>中的一个键可以对应多个元素值,即一个序列。所以在操作符ToLookup调用时,系统把输入序列中每一个类型为T的元素传递给委托keySelector,委托keySelector根据传入的参数生成一个类型为K的新对象key,并将一系列与该对象key对应的所有输入元素组成键和值添加到返回的集合结果中。其他操作符ToLookup的原型方法的实现功能和操作符ToDictionary没什么区别;

  (4)示例验证

①自定义工资比较类

工资比较类
 1 //工资比较类
2 publicclass SalaryWageComparer:IEqualityComparer<double>
3 {
4 publicbool Equals(double wage1, double wage2)
5 {
6 return wage1 == wage2;
7 }
8
9 publicint GetHashCode(double wage)
10 {
11 return wage.GetHashCode();
12 }
13 }

②调用ToLookup操作符

ToLookup操作符
 1 staticvoid Main(string[] args)
2 {
3 //定义雇员薪水数组
4 Salary[] salarys =new Salary[]
5 {
6 new Salary{EmployeeId="0001",Wage=1700,Bonus=2500,SalaryTime=new DateTime(2011,7,15)},
7 new Salary{EmployeeId="0002",Wage=1500,Bonus=2500,SalaryTime=new DateTime(2011,7,15)},
8 new Salary{EmployeeId="0003",Wage=1700,Bonus=3000,SalaryTime=new DateTime(2011,7,15)},
9 new Salary{EmployeeId="0004",Wage=1000,Bonus=2000,SalaryTime=new DateTime(2011,7,15)},
10 new Salary{EmployeeId="0005",Wage=2000,Bonus=4000,SalaryTime=new DateTime(2011,7,15)},
11 new Salary{EmployeeId="0006",Wage=1000,Bonus=2000,SalaryTime=new DateTime(2011,7,15)},
12 new Salary{EmployeeId="0007",Wage=3000,Bonus=5000,SalaryTime=new DateTime(2011,7,15)},
13 new Salary{EmployeeId="0001",Wage=1700,Bonus=3000,SalaryTime=new DateTime(2011,8,15)},
14 new Salary{EmployeeId="0002",Wage=1500,Bonus=3000,SalaryTime=new DateTime(2011,8,15)},
15 new Salary{EmployeeId="0003",Wage=1700,Bonus=4000,SalaryTime=new DateTime(2011,8,15)},
16 };
17
18 //ToLookup第一个原型
19 Console.WriteLine("调用ToLookup操作符第一个方法原型:");
20 Console.WriteLine("------------------------------------");
21
22 ILookup<string, Salary> salarylookup = salarys.ToLookup(s=>s.EmployeeId);
23
24 Console.WriteLine("0002号雇员的薪水发放情况:");
25 foreach (var s in salarylookup["0002"])
26 {
27 Console.WriteLine(s.ToString());
28 }
29
30 Console.WriteLine("***************************************************");
31
32 //ToLookup第二个原型
33 Console.WriteLine("调用ToLookup操作符第二个方法原型:");
34 Console.WriteLine("------------------------------------");
35
36 //生成一个工资比较类的辅助对象
37 SalaryWageComparer awc =new SalaryWageComparer();
38
39 ILookup<double, Salary> salarylookup1 = salarys.ToLookup(s => s.Wage, awc);
40
41 Console.WriteLine("工资在1700的雇员:");
42 foreach (var s in salarylookup1[1700])
43 {
44 Console.WriteLine(s.ToString());
45 }
46
47 Console.WriteLine("***************************************************");
48
49 //ToLookup第三个原型
50 Console.WriteLine("调用ToLookup操作符第三个方法原型:");
51 Console.WriteLine("------------------------------------");
52
53 var salarylookup2 = salarys.ToLookup(s => s.SalaryTime.ToString("yyyy-MM"), s =>new { EmployeeId = s.EmployeeId, Wage = s.Wage, Bonus = s.Bonus });
54
55 Console.WriteLine("在2011年8月份薪水发放情况:");
56 foreach (var s in salarylookup2["2011-08"])
57 {
58 Console.WriteLine(s);
59 }
60
61 Console.WriteLine("***************************************************");
62
63 //ToLookup第四个原型
64 Console.WriteLine("调用ToLookup操作符第四个方法原型:");
65 Console.WriteLine("------------------------------------");
66
67 SalaryWageComparer awc1 =new SalaryWageComparer();
68
69 var salarylookup3 = salarys.ToLookup(s => s.Wage, s =>new { EmployeeId = s.EmployeeId, SalaryTime = s.SalaryTime }, awc1);
70
71 Console.WriteLine("工资在1700的雇员(雇员号与发薪日期):");
72 foreach (var s in salarylookup3[1700])
73 {
74 Console.WriteLine(s);
75 }
76
77 Console.Read();
78 }

③结果

 5.SequenceEqual操作符

  (1)作用:用于判断两个序列是否相等;

  (2)方法原型

    ①原型定义:

    public static bool SequenceEqual<T>(

    this IEnumerable<T> first,

    IEnumerable<T> second);

    ②原型定义:

    public static bool SequenceEqual<T>(

    this IEnumerable<T> first,

    IEnumerable<T> second,

    IEqualityComparer<T> comparer);

  (3)原型说明:操作符SequenceEqual的第一种方法原型接收两个输入序列first和second,并使用System.Object.Equals方法来比较这两个输入序列中的元素是否相等,只有当两个序列元素个数相同且对应元素相等才认为这两个序列相同,即返回ture,否则返回false。要注意比较的这两个序列的元素类型必须相同。相比较于第一种方法原型,第二种方法多了一个类型为IEqualityComparer<T>类型的参数,就像前两个操作符一样,该参数也是用于比较元素之间的相等逻辑,可以由开发人员自定义其实现方法;

  (4)示例验证

SequenceEqual操作符
 1 staticvoid Main(string[] args)
2 {
3 //定义数组
4 char[] ch_array =newchar[] { 'A', 'B', 'C', 'D', 'E' };
5 char[] ch_array1 =newchar[] { 'A', 'B', 'C', 'D', 'E'};
6
7 //SequenceEqual第一个原型
8 Console.WriteLine("调用SequenceEqual操作符第一个方法原型:");
9 Console.WriteLine("------------------------------------");
10
11 bool flag = ch_array.SequenceEqual(ch_array1);
12 if (flag)
13 Console.WriteLine("序列ch_array和序列ch_array1相同!");
14 else
15 Console.WriteLine("序列ch_array和序列ch_array1不同!");
16
17 Console.WriteLine("***************************************************");
18
19 //SequenceEqual第二个原型
20 Console.WriteLine("调用SequenceEqual操作符第二个方法原型:");
21 Console.WriteLine("------------------------------------");
22
23 //生成一个字符比较类的辅助对象
24 CharComparer cc =new CharComparer();
25
26 bool flag1 = ch_array.SequenceEqual(ch_array1,cc);
27 if (flag)
28 Console.WriteLine("序列ch_array和序列ch_array1相同(含有辅助比较对象)!");
29 else
30 Console.WriteLine("序列ch_array和序列ch_array1不同(含有辅助比较对象)!");
31
32 Console.Read();
33 }

结果

  6.First操作符

  (1)作用:用于返回输入序列中的第一个元素或者满足条件的第一个元素;

  (2)方法原型

    ①原型定义:

    public static T First<T>(

    this IEnumerable<T> source);

    ②原型定义:

    public static T First<T>(

    this IEnumerable<T> source,

    Func<T,bool> predicate);

  (3)原型说明:操作符First第一个方法原型接收一个输入序列source,并且返回source序列中的第一个元素。相比第一种方法原型,第二种则多了一个委托参数predicate,系统把输入序列source中的每一个元素传递给委托predicate,只有使委托predicate对应的具体方法返回值为true的第一个元素才会返回;

  (4)示例验证

First操作符
 1 staticvoid Main(string[] args)
2 {
3 //定义雇员数组
4 Employee[] employees =new Employee[]
5 {
6 new Employee{Id="0001",Name="张三",Age=32},
7 new Employee{Id="0002",Name="李四",Age=31},
8 new Employee{Id="0003",Name="王五",Age=32},
9 new Employee{Id="0004",Name="小六",Age=25},
10 new Employee{Id="0005",Name="张麻子",Age=40},
11 new Employee{Id="0006",Name="王小二",Age=25},
12 new Employee{Id="0007",Name="灭绝师太",Age=55},
13 };
14
15 //定义雇员薪水数组
16 Salary[] salarys =new Salary[]
17 {
18 new Salary{EmployeeId="0001",Wage=1700,Bonus=2500,SalaryTime=new DateTime(2011,7,15)},
19 new Salary{EmployeeId="0002",Wage=1500,Bonus=2500,SalaryTime=new DateTime(2011,7,15)},
20 new Salary{EmployeeId="0003",Wage=1700,Bonus=3000,SalaryTime=new DateTime(2011,7,15)},
21 new Salary{EmployeeId="0004",Wage=1000,Bonus=2000,SalaryTime=new DateTime(2011,7,15)},
22 new Salary{EmployeeId="0005",Wage=2000,Bonus=4000,SalaryTime=new DateTime(2011,7,15)},
23 new Salary{EmployeeId="0006",Wage=1000,Bonus=2000,SalaryTime=new DateTime(2011,7,15)},
24 new Salary{EmployeeId="0007",Wage=3000,Bonus=5000,SalaryTime=new DateTime(2011,7,15)},
25 new Salary{EmployeeId="0001",Wage=1700,Bonus=3000,SalaryTime=new DateTime(2011,8,15)},
26 new Salary{EmployeeId="0002",Wage=1500,Bonus=3000,SalaryTime=new DateTime(2011,8,15)},
27 new Salary{EmployeeId="0003",Wage=1700,Bonus=4000,SalaryTime=new DateTime(2011,8,15)},
28 };
29
30 //First第一个原型
31 Console.WriteLine("调用First操作符第一个方法原型:");
32 Console.WriteLine("------------------------------------");
33
34 Employee employee2 = employees.First();
35
36 Console.WriteLine("序列中的第一个元素:");
37 Console.WriteLine(employee2.ToString());
38
39 Console.WriteLine("***************************************************");
40
41 //First第二个原型
42 Console.WriteLine("调用First操作符第二个方法原型:");
43 Console.WriteLine("------------------------------------");
44
45 Salary salary=salarys.First(s=>s.EmployeeId=="0003");
46
47 Console.WriteLine("薪水序列中雇员号是0003的第一个元素:");
48 Console.WriteLine(salary.ToString());
49
50 Console.Read();
51 }

结果

  7.FirstOrDefault操作符

  (1)作用:用于找到输入序列中的第一个元素或者满足条件的第一个元素并返回,若没有找到,则返回一个相关类型的默认值元素;

  (2)方法原型

    ①原型定义:

    public static T FirstOrDefault<T>(

    this IEnumerable<T> source);

    ②原型定义:

    public static T FirstOrDefault<T>(

    this IEnumerable<T> source,

    Func<T,bool> predicate);

  (3)原型说明:操作符FirstOrDefault的原型定义和First操作符一样,且两个方法实现也基本相同,只不过First操作符在找不到相应的元素时,会抛出一个异常,而操作符FirstOrDefault若没有找到,则返回一个相关类型的默认值default(T)。如果输入序列中的元素为引用类型则默认值为null,如果是值类型的,则返回该类型的默认值

  (4)示例验证

FirstOrDefault操作符
 1 staticvoid Main(string[] args)
2 {
3 //定义雇员数组
4 Employee[] employees =new Employee[]
5 {
6 new Employee{Id="0001",Name="张三",Age=32},
7 new Employee{Id="0002",Name="李四",Age=31},
8 new Employee{Id="0003",Name="王五",Age=32},
9 new Employee{Id="0004",Name="小六",Age=25},
10 new Employee{Id="0005",Name="张麻子",Age=40},
11 new Employee{Id="0006",Name="王小二",Age=25},
12 new Employee{Id="0007",Name="灭绝师太",Age=55},
13 };
14
15 //定义雇员薪水数组
16 Salary[] salarys =new Salary[]
17 {
18 new Salary{EmployeeId="0001",Wage=1700,Bonus=2500,SalaryTime=new DateTime(2011,7,15)},
19 new Salary{EmployeeId="0002",Wage=1500,Bonus=2500,SalaryTime=new DateTime(2011,7,15)},
20 new Salary{EmployeeId="0003",Wage=1700,Bonus=3000,SalaryTime=new DateTime(2011,7,15)},
21 new Salary{EmployeeId="0004",Wage=1000,Bonus=2000,SalaryTime=new DateTime(2011,7,15)},
22 new Salary{EmployeeId="0005",Wage=2000,Bonus=4000,SalaryTime=new DateTime(2011,7,15)},
23 new Salary{EmployeeId="0006",Wage=1000,Bonus=2000,SalaryTime=new DateTime(2011,7,15)},
24 new Salary{EmployeeId="0007",Wage=3000,Bonus=5000,SalaryTime=new DateTime(2011,7,15)},
25 new Salary{EmployeeId="0001",Wage=1700,Bonus=3000,SalaryTime=new DateTime(2011,8,15)},
26 new Salary{EmployeeId="0002",Wage=1500,Bonus=3000,SalaryTime=new DateTime(2011,8,15)},
27 new Salary{EmployeeId="0003",Wage=1700,Bonus=4000,SalaryTime=new DateTime(2011,8,15)},
28 };
29
30 //FirstOrDefault第一个原型
31 Console.WriteLine("调用FirstOrDefault操作符第一个方法原型:");
32 Console.WriteLine("------------------------------------");
33
34 Employee employee3 = employees.Where(e => e.Age <18).FirstOrDefault();
35
36 Console.WriteLine("雇员中年龄小于18周岁:");
37 Console.WriteLine(employee3);
38
39 Console.WriteLine("***************************************************");
40
41 //FirstOrDefault第二个原型
42 Console.WriteLine("调用FirstOrDefault操作符第二个方法原型:");
43 Console.WriteLine("------------------------------------");
44
45 Salary salary1 = salarys.FirstOrDefault(s => s.Bonus>8000);
46
47 Console.WriteLine("薪水序列中奖金高于8000:");
48 Console.WriteLine(salary1);
49
50 Console.Read();
51 }

结果

  8.Last操作符

  (1)作用:用于返回输入序列的最后一个元素或者满足条件的最后一个元素;

  (2)方法原型

    ①原型定义:

    public static T Last<T>(

    this IEnumerable<T> source);

    ②原型定义:

    public static T Last<T>(

    this IEnumerable<T> source,

    Func<T,bool> predicate);

  (3)原型说明:操作符Last的方法原型和First操作符的一样,并且方法的实现也基本相同,唯一的区别在于操作符Last返回的是序列中的最后一个元素,而First操作符是返回序列中的第一个元素;

  (4)示例验证

Last操作符
 1 staticvoid Main(string[] args)
2 {
3 //定义雇员数组
4 Employee[] employees =new Employee[]
5 {
6 new Employee{Id="0001",Name="张三",Age=32},
7 new Employee{Id="0002",Name="李四",Age=31},
8 new Employee{Id="0003",Name="王五",Age=32},
9 new Employee{Id="0004",Name="小六",Age=25},
10 new Employee{Id="0005",Name="张麻子",Age=40},
11 new Employee{Id="0006",Name="王小二",Age=25},
12 new Employee{Id="0007",Name="灭绝师太",Age=55},
13 };
14
15 //定义雇员薪水数组
16 Salary[] salarys =new Salary[]
17 {
18 new Salary{EmployeeId="0001",Wage=1700,Bonus=2500,SalaryTime=new DateTime(2011,7,15)},
19 new Salary{EmployeeId="0002",Wage=1500,Bonus=2500,SalaryTime=new DateTime(2011,7,15)},
20 new Salary{EmployeeId="0003",Wage=1700,Bonus=3000,SalaryTime=new DateTime(2011,7,15)},
21 new Salary{EmployeeId="0004",Wage=1000,Bonus=2000,SalaryTime=new DateTime(2011,7,15)},
22 new Salary{EmployeeId="0005",Wage=2000,Bonus=4000,SalaryTime=new DateTime(2011,7,15)},
23 new Salary{EmployeeId="0006",Wage=1000,Bonus=2000,SalaryTime=new DateTime(2011,7,15)},
24 new Salary{EmployeeId="0007",Wage=3000,Bonus=5000,SalaryTime=new DateTime(2011,7,15)},
25 new Salary{EmployeeId="0001",Wage=1700,Bonus=3000,SalaryTime=new DateTime(2011,8,15)},
26 new Salary{EmployeeId="0002",Wage=1500,Bonus=3000,SalaryTime=new DateTime(2011,8,15)},
27 new Salary{EmployeeId="0003",Wage=1700,Bonus=4000,SalaryTime=new DateTime(2011,8,15)},
28 };
29
30 //Last第一个原型
31 Console.WriteLine("调用Last操作符第一个方法原型:");
32 Console.WriteLine("------------------------------------");
33
34 Employee employee4 = employees.Last();
35
36 Console.WriteLine("序列中的最后一个元素:");
37 Console.WriteLine(employee4.ToString());
38
39 Console.WriteLine("***************************************************");
40
41 //Last第二个原型
42 Console.WriteLine("调用Last操作符第二个方法原型:");
43 Console.WriteLine("------------------------------------");
44
45 Salary salary2 = salarys.Last(s => s.EmployeeId =="0003");
46
47 Console.WriteLine("薪水序列中最后一个雇员号是0003的元素:");
48 Console.WriteLine(salary2.ToString());
49
50 Console.Read();
51 }

结果

  9.LastOrDefault操作符

  (1)作用:用于找到输入序列中的最后一个元素或者满足条件的最后一个元素并返回,若没有找到,则返回一个相关类型的默认值元素;

  (2)方法原型

    ①原型定义:

    public static T LastOrDefault<T>(

    this IEnumerable<T> source);

    ②原型定义:

    public static T LastOrDefault<T>(

    this IEnumerable<T> source,

    Func<T,bool> predicate);

  (3)原型说明:和First操作符一样,Last操作符也有对应的LastOrDefault操作符,方法原型和方法实现与FirstOrDefault操作符相同,唯一的不同就是操作符LastOrDefault返回的是序列中的最后一个元素,而FirstOrDefault操作符是返回序列中的第一个元素;

  (4)示例验证

LastOrDefault操作符
 1 staticvoid Main(string[] args)
2 {
3 //定义雇员数组
4 Employee[] employees =new Employee[]
5 {
6 new Employee{Id="0001",Name="张三",Age=32},
7 new Employee{Id="0002",Name="李四",Age=31},
8 new Employee{Id="0003",Name="王五",Age=32},
9 new Employee{Id="0004",Name="小六",Age=25},
10 new Employee{Id="0005",Name="张麻子",Age=40},
11 new Employee{Id="0006",Name="王小二",Age=25},
12 new Employee{Id="0007",Name="灭绝师太",Age=55},
13 };
14
15 //定义雇员薪水数组
16 Salary[] salarys =new Salary[]
17 {
18 new Salary{EmployeeId="0001",Wage=1700,Bonus=2500,SalaryTime=new DateTime(2011,7,15)},
19 new Salary{EmployeeId="0002",Wage=1500,Bonus=2500,SalaryTime=new DateTime(2011,7,15)},
20 new Salary{EmployeeId="0003",Wage=1700,Bonus=3000,SalaryTime=new DateTime(2011,7,15)},
21 new Salary{EmployeeId="0004",Wage=1000,Bonus=2000,SalaryTime=new DateTime(2011,7,15)},
22 new Salary{EmployeeId="0005",Wage=2000,Bonus=4000,SalaryTime=new DateTime(2011,7,15)},
23 new Salary{EmployeeId="0006",Wage=1000,Bonus=2000,SalaryTime=new DateTime(2011,7,15)},
24 new Salary{EmployeeId="0007",Wage=3000,Bonus=5000,SalaryTime=new DateTime(2011,7,15)},
25 new Salary{EmployeeId="0001",Wage=1700,Bonus=3000,SalaryTime=new DateTime(2011,8,15)},
26 new Salary{EmployeeId="0002",Wage=1500,Bonus=3000,SalaryTime=new DateTime(2011,8,15)},
27 new Salary{EmployeeId="0003",Wage=1700,Bonus=4000,SalaryTime=new DateTime(2011,8,15)},
28 };
29
30 //LastOrDefault第一个原型
31 Console.WriteLine("调用LastOrDefault操作符第一个方法原型:");
32 Console.WriteLine("------------------------------------");
33
34 Employee employee5 = employees.Where(e => e.Age>60).FirstOrDefault();
35
36 Console.WriteLine("雇员中年龄大于60周岁:");
37 Console.WriteLine(employee5);
38
39 Console.WriteLine("***************************************************");
40
41 //LastOrDefault第二个原型
42 Console.WriteLine("调用LastOrDefault操作符第二个方法原型:");
43 Console.WriteLine("------------------------------------");
44
45 Salary salary3 = salarys.FirstOrDefault(s => s.Bonus <2000);
46
47 Console.WriteLine("薪水序列中奖金低于2000:");
48 Console.WriteLine(salary3);
49
50 Console.Read();
51 }

结果

  10.Single操作符

  (1)作用:用于从输入序列中返回唯一的元素或满足条件的唯一元素;

  (2)方法原型

    ①原型定义:

    public static T Single<T>(

    this IEnumerable<T> source);

    ②原型定义:

    public static T Single<T>(

    this IEnumerable<T> source,

    Func<T,bool> predicate);

  (3)原型说明:操作符Single的第一个方法原型,要求输入的序列只能包含唯一一个元素,如果输入序列中元素为零个或多于一个,抛出异常。而第二个方法原型中允许输入序列可以有多个元素,且比第一种方法原型还多了一个委托参数predicate,当调用操作符Single时,系统把输入序列中的每一个元素作为输入参数传递给委托predicate,只有使得委托predicate的返回值为true,且只有唯一的元素才会返回。如果没有元素使得委托predicate返回值为true,或使得委托predicate返回值为true的元素有多个,则Single操作符就会抛出异常

  (4)示例验证

Single操作符
 1 staticvoid Main(string[] args)
2 {
3 //定义雇员数组
4 Employee[] employees =new Employee[]
5 {
6 new Employee{Id="0001",Name="张三",Age=32},
7 new Employee{Id="0002",Name="李四",Age=31},
8 new Employee{Id="0003",Name="王五",Age=32},
9 new Employee{Id="0004",Name="小六",Age=25},
10 new Employee{Id="0005",Name="张麻子",Age=40},
11 new Employee{Id="0006",Name="王小二",Age=25},
12 new Employee{Id="0007",Name="灭绝师太",Age=55},
13 };
14
15 //Single第一个原型
16 Console.WriteLine("调用Single操作符第一个方法原型:");
17 Console.WriteLine("------------------------------------");
18
19 Employee employee6 = employees.Where(e=>e.Id=="0006").Single();
20
21 Console.WriteLine("0006号雇员:");
22 Console.WriteLine(employee6.ToString());
23
24 Console.WriteLine("***************************************************");
25
26 //Single第二个原型
27 Console.WriteLine("调用Single操作符第二个方法原型:");
28 Console.WriteLine("------------------------------------");
29
30 Employee employee7 = employees.Single(e=>e.Id=="0006");
31
32 Console.WriteLine("0006号雇员:");
33 Console.WriteLine(employee7.ToString());
34
35 Console.Read();
36 }

结果

  11.SingleOrDefault操作符

  (1)作用:用于从输入序列中找到唯一的元素或满足条件的唯一元素,若没有找到,则返回一个相关类型默认值元素;

  (2)方法原型

    ①原型定义:

    public static T SingleOrDefault<T>(

    this IEnumerable<T> source);

    ②原型定义:

    public static T SingleOrDefault<T>(

    this IEnumerable<T> source,

    Func<T,bool> predicate);

  (3)原型说明:操作符SingleOrDefault的方法原型和Single操作符一样,第一种方法原型要求输入序列只能包含一个元素,如果没有元素则返回一个默认值default(T),但多个元素则SingleOrDefault操作符还是会抛出异常。而第二个方法原型中允许输入序列可以有多个元素,且比第一种方法原型还多了一个委托参数predicate,当调用操作符SingleOrDefault时,系统把输入序列中的每一个元素作为输入参数传递给委托predicate,只有使得委托predicate的返回值为true,且只有唯一的元素才会返回。如果没有元素使得委托predicate返回值为true,则返回默认值default(T)。但如果使得委托predicate返回值为true的元素有多个,则SingleOrDefault操作符还是会抛出异常;

  (4)示例验证

SingleOrDefault操作符
 1 staticvoid Main(string[] args)
2 {
3 //定义雇员数组
4 Employee[] employees =new Employee[]
5 {
6 new Employee{Id="0001",Name="张三",Age=32},
7 new Employee{Id="0002",Name="李四",Age=31},
8 new Employee{Id="0003",Name="王五",Age=32},
9 new Employee{Id="0004",Name="小六",Age=25},
10 new Employee{Id="0005",Name="张麻子",Age=40},
11 new Employee{Id="0006",Name="王小二",Age=25},
12 new Employee{Id="0007",Name="灭绝师太",Age=55},
13 };
14
15 //定义雇员薪水数组
16 Salary[] salarys =new Salary[]
17 {
18 new Salary{EmployeeId="0001",Wage=1700,Bonus=2500,SalaryTime=new DateTime(2011,7,15)},
19 new Salary{EmployeeId="0002",Wage=1500,Bonus=2500,SalaryTime=new DateTime(2011,7,15)},
20 new Salary{EmployeeId="0003",Wage=1700,Bonus=3000,SalaryTime=new DateTime(2011,7,15)},
21 new Salary{EmployeeId="0004",Wage=1000,Bonus=2000,SalaryTime=new DateTime(2011,7,15)},
22 new Salary{EmployeeId="0005",Wage=2000,Bonus=4000,SalaryTime=new DateTime(2011,7,15)},
23 new Salary{EmployeeId="0006",Wage=1000,Bonus=2000,SalaryTime=new DateTime(2011,7,15)},
24 new Salary{EmployeeId="0007",Wage=3000,Bonus=5000,SalaryTime=new DateTime(2011,7,15)},
25 new Salary{EmployeeId="0001",Wage=1700,Bonus=3000,SalaryTime=new DateTime(2011,8,15)},
26 new Salary{EmployeeId="0002",Wage=1500,Bonus=3000,SalaryTime=new DateTime(2011,8,15)},
27 new Salary{EmployeeId="0003",Wage=1700,Bonus=4000,SalaryTime=new DateTime(2011,8,15)},
28 };
29
30 //SingleOrDefault第一个原型
31 Console.WriteLine("调用SingleOrDefault操作符第一个方法原型:");
32 Console.WriteLine("------------------------------------");
33
34 Employee employee8 = employees.Where(e => e.Age>60).SingleOrDefault();
35
36 Console.WriteLine("年龄大于60周岁的雇员:");
37 Console.WriteLine(employee8);
38
39 Console.WriteLine("***************************************************");
40
41 //SingleOrDefault第二个原型
42 Console.WriteLine("调用SingleOrDefault操作符第二个方法原型:");
43 Console.WriteLine("------------------------------------");
44
45 Salary salary4 = salarys.SingleOrDefault(e=>(e.Bonus+e.Wage)>10000);
46
47 Console.WriteLine("薪水大于10000:");
48 Console.WriteLine(salary4);
49
50 Console.Read();
51 }

结果

posted @ 2011-09-03 16:38  Rookie_J  阅读(1124)  评论(5编辑  收藏  举报