服务器之家:专注于服务器技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - C# - C#使用LINQ中Enumerable类方法的延迟与立即执行的控制

C#使用LINQ中Enumerable类方法的延迟与立即执行的控制

2021-11-15 14:33DebugLZQ C#

这篇文章主要介绍了C#的LINQ查询中Enumerable类方法的延迟与立即执行,LINQ语言集成查询可以让C#和VB以查询数据库相同的方式操作内存数据,需要的朋友可以参考下

延时执行的enumerable类方法

linq标准查询运算法是依靠一组扩展方法来实现的。而这些扩展方法分别在system.linq.enumerable和system.linq.queryable这连个静态类中定义。

  enumerable的扩展方法采用线性流程,每个运算法会被线性执行。这种执行方法如果操作类似关系型数据库数据源,效率会非常低下,所以queryable重新定义这些扩展方法,把linq表达式拆解为表达式树,提供程序就可以根据表达式树生成关系型数据库的查询语句,即sql命令,然后进行相关操作。

  每个查询运算符的执行行为不同,大致分为立即执行和延时执行。延时执行的运算符将在枚举元素的时候被执行。

  enumerable类位于程序集system.core.dll中,system.linq命名空间下,并且直接集成自system.object,存在于3.5及以上的.net框架中。enumerable是静态类,不能实例化和被继承,其成员只有一组静态和扩展方法。

  linq不仅能够查询实现ienumerable<t>或iqueryable<t>的类型,也能查询实现ienumerable接口的类型。

理解linq首先必须理解扩展方法

  msdn是这样规定扩展方法的:“扩展方法被定义为静态方法,但它们是通过实例方法语法进行调用的。 它们的第一个参数指定该方法作用于哪个类型,并且该参数以 this 修饰符为前缀。”

下面给个扩展方法的例子如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
using system;
using system.collections.generic;
using system.linq;
using system.text;
 
namespace 扩展方法
{
  /// <summary>
  /// 为string类型定义一个扩展方法
  /// </summary>
  static class helper
  {
    public static string myextenmethod(this string s)
    {
      return s.substring(0, 2);
    }
  }
  class program
  {
    static void main(string[] args)
    {
      string s = "扩展方法示例";
      console.writeline(s.myextenmethod());//调用
      console.readkey(false);
    }
  }
}

程序的运行结果如下:

C#使用LINQ中Enumerable类方法的延迟与立即执行的控制

为了方便理解和记忆,将常用的延时执行的enumerable类方法成员分了下组,具体如下:

1.take用于从一个序列的开头返回指定数量的元素

2.takewhile 用于获取指定序列从头开始符合条件的元素,直到遇到不符合条件的元素为止

3.skip跳过序列中指定数量的元素

4.skipwhile 用于跳过序列总满足条件的元素,然会返回剩下的元素

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
using system;
using system.collections.generic;
using system.linq;
using system.text;
 
namespace 延时执行的enumerable类方法
{
  class program
  {
    static void main(string[] args)
    {
      string[] names = { "debuglzq","debugman","sarah","jerry","tom","linda","m&m","jeffery"};
      //1.take用于从一个序列的开头返回指定数量的元素
      //
      //a.在数组上直接使用take方法
      foreach (string name in names.take(3))
      {
        console.write("{0}  ", name);
      }
      console.writeline();
      console.writeline("-----");
      //b.在linq返回的ienumerable<t>序列上使用take方法
      var query = from string name in names
            where name.length <=3
            select name;
      foreach (string name in query.take(1))
      {
        console.write("{0}  ",name);
      }
      console.writeline();
      console.writeline("----------------------------");
      console.readkey(false);
      //2.takewhile 用于获取指定序列从头开始符合条件的元素,直到遇到不符合条件的元素为止
      //
      var takenames = names.takewhile(n => n.length>4);
      var takenames2 = names.takewhile((n,i)=>n.length<10&&i<3);
      foreach (string name in takenames)
      {
        console.write("{0}  ", name);
      }
      console.writeline();
      console.writeline("-----");
      foreach (string name in takenames2)
      {
        console.write("{0}  ", name);
      }
      console.writeline();
      console.writeline("----------------------------");
      console.readkey(false);
      //3.skip跳过序列中指定数量的元素
      //
      foreach (string name in names.skip(5))
      {
        console.write("{0}  ", name);
      }
      console.writeline();
      console.writeline("-----");
      var query_skip = (from name in names
               where name.length >= 3
               select name).skip(2);
      foreach (string name in query_skip.skip(2) )
      {
        console.write("{0}  ", name);
      }
      console.writeline();
      console.writeline("----------------------------");
      console.readkey(false);
      //4.skipwhile 用于跳过序列总满足条件的元素,然会返回剩下的元素
      //跳过名字长度大于3的
      var takenames_skipwhile = names.skipwhile(n => n.length >3);
      foreach (string name in takenames_skipwhile)
      {
        console.write("{0}  ", name);
      }
      console.writeline();
      console.writeline("-----");
      var takenames_skipwhile2 = names.skipwhile((n,i)=>n.length>3&&i>2);
      foreach (string name in takenames_skipwhile2)
      {
        console.write("{0}  ", name);
      }
      console.writeline();
      console.writeline("----------------------------");
      console.readkey(false);
 
      //小结take、skip获得第n到第m个元素
      var names_takeandskip = names.skip(5).take(3);
 
      var names_takeandskip2 = (from name in names
                   select name).skip(5).take(3);
 
      foreach (string name in names_takeandskip)
      {
        console.write("{0}  ", name);
      }
      console.writeline();
      console.writeline("-----");
      foreach (string name in names_takeandskip2)
      {
        console.write("{0}  ", name);
      }
      console.writeline();
      console.writeline("----------------------------");
      console.readkey(false);
 
    }
  }
}

程序中有详细的注释不再多做说明,程序运行结果如下:

C#使用LINQ中Enumerable类方法的延迟与立即执行的控制

5.reverse用于翻转序列中的元素的顺序

6.distinct过滤掉重复的元素

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
using system;
using system.collections.generic;
using system.linq;
using system.text;
 
namespace reverse_distinct等
{
  class program
  {
    static void main(string[] args)
    {
      string[] names = { "debuglzq", "jerry", "sarah", "jerry", "tom", "linda", "m&m", "jeffery" };
      //5.reverse用于翻转序列中的元素的顺序
      string str = "反转字符串";
 
      var strre = str.tochararray().reverse();
      var takenames = names.reverse();
 
      foreach (var c in strre)
      {
        console.write(c);
      }
      console.writeline();
      console.writeline("-----");
      foreach (var c in takenames )
      {
        console.writeline(c);
      }
      console.writeline("----------------------------");
      console.readkey(false);
 
      //6.distinct 过滤掉重复的元素
      var takenames_distinct = names.distinct();
 
      foreach (var c in takenames_distinct)
      {
        console.writeline(c);
      }
      console.writeline("----------------------------");
      console.readkey(false);
    }
  }
}

程序的运行结果如下:

C#使用LINQ中Enumerable类方法的延迟与立即执行的控制

7.union用于合并两个序列,并去掉重复项

8.concat用于连接两个序列,不会去掉重复项

9.intersect用于获得连个序列的交集

10.except用于获得两个结合的差集

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
using system;
using system.collections.generic;
using system.linq;
using system.text;
 
namespace union_concat_intersect_except
{
  /// <summary>
  /// debuglzq
  /// http://www.cnblogs.com/debuglzq
  /// </summary>
  class program
  {
    static void main(string[] args)
    {
      string[] names1 = { "debuglzq", "jerry", "sarah", "jerry", "tom", "linda", "m&m", "jeffery" };
      string[] names2 = { "debuglzq", "jerry", "sarah" };
 
      //7.union用于合并两个序列,并去掉重复项
      var names_union = names1.union(names2);
 
      //8.concat用于连接两个序列,不会去掉重复项
      var names_concat = names1.concat(names2);
 
      //9.intersect用于获得连个序列的交集
      var names_intersect = names1.intersect(names2);
 
      //10.except用于获得两个结合的差集
      var names_except = names1.except(names2);
 
      foreach (string name in names_union)
      {
        console.writeline(name);
      }
      console.writeline("-----");
      console.readkey(false);
      foreach (string name in names_concat)
      {
        console.writeline(name);
      }
      console.writeline("-----");
      console.readkey(false);
      foreach (string name in names_intersect)
      {
        console.writeline(name);
      }
      console.writeline("-----");
      console.readkey(false);
      foreach (string name in names_except)
      {
        console.writeline(name);
      }
      console.writeline("-----");
      console.readkey(false);
    }
  }
}

程序的运行结果如下:

C#使用LINQ中Enumerable类方法的延迟与立即执行的控制

11.range 用于生成指定范围内的“整数”序列

12.repeat用于生成指定数量的重复元素

13.empty 用于获得一个指定类型的空序列

14.defaultifempty 用于获得序列,如果为空,则添加一个默认类型元素

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
using system;
using system.collections.generic;
using system.linq;
using system.text;
 
namespace range_empty_defalultifempty
{
  /// <summary>
  /// debuglzq
  /// http://www.cnblogs.com/debuglzq
  /// </summary>
  class program
  {
    static void main(string[] args)
    {
      //11.range 用于生成指定范围内的“整数”序列
      var num2 = enumerable.range(10, 15);
 
      //12.repeat用于生成指定数量的重复元素
      var guest = new {name="橙子",age=25 };
      var guests = enumerable.repeat(guest, 5);
 
      //13.empty 用于获得一个指定类型的空序列
      var empty = enumerable.empty<string>();
 
      //14.defaultifempty 用于获得序列,如果为空,则添加一个默认类型元素
      //a
      var intempty = enumerable.empty<int>();
      console.writeline(intempty.count());
      console.writeline("-----------");
      foreach (var n in intempty)
      {
        console.writeline(n);     
      }
      console.writeline("-----------");
      console.writeline(intempty.defaultifempty().count());
      console.writeline("-----------");
      foreach (var n in intempty.defaultifempty())
      {
        console.writeline(n);
      }
      console.writeline("--------------------------");
      console.readkey(false);
      //b
      string[] names = { "debuglzq", "debugman", "sarah", "jerry", "tom", "linda", "m&m", "jeffery" };
      var query = from name in names
            where name == "lbj"
            select name;
      console.writeline(query.count());
      console.writeline(query.defaultifempty().count());//默认为null
      foreach (var n in query.defaultifempty())
      {
        console.writeline(n);
      }
      console.writeline("---------------");
      console.readkey(false);
      //c指定一个默认值
      foreach (var n in intempty.defaultifempty(100))
      {
        console.writeline(n);
      }
      console.writeline("--------------------------");
      console.readkey(false);
 
      foreach (var n in query.defaultifempty("james"))
      {
        console.writeline(n);
      }
      console.readkey(false);
    }
  }
}

程序的运行结果如下:

C#使用LINQ中Enumerable类方法的延迟与立即执行的控制

15.oftype筛选指定类型的元素

16.cast类型转换

17.asenumerable有些数据源类型不支持enumerable的部分查询关键字,需要转换下,譬如iqueryable

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
using system;
using system.collections.generic;
using system.linq;
using system.text;
using system.collections;
 
namespace cast_oftype_asenumerable
{
  /// <summary>
  /// debuglzq
  /// http://www.cnblogs.com/debuglzq
  /// </summary>
  class program
  {
    static void main(string[] args)
    {
      arraylist names = new arraylist();
      names.add("debuglzq");
      names.add("jerry");
      names.add(100);
      names.add(new {name="lzq",age=26});
      names.add(new stack());
      //15.oftype筛选指定类型的元素
      var takenames = names.oftype<string>();
 
      //16.cast类型转换
      var takenames2 = names.oftype<string>().cast<string>();
 
      //17.asenumerable
      var takenames3 = takenames2.asenumerable();
 
      foreach (var name in takenames3)
      {
        console.write("{0} ",name);
      }
      console.readkey(false);
 
    }
  }
}

程序运行结果如下:

C#使用LINQ中Enumerable类方法的延迟与立即执行的控制

延时执行,顾名思义就是不是立即执行,即不是在查询语句定义的时候执行,而是在处理结果集(如遍历)的时候执行,在enumerable类方法成员中,除了本节总结的这常用的17个外,前面博文---linq基本子句 中总结的8个基本子句也都是延时执行的。注意延时执行的查询程序的执行流程。

立即执行的enumerable类方法
下面我们再来总结常用的立即执行的enumerable类方法和它们的常用用法。同样,为了便于理解和记忆,进行一下分组:

1.toarray序列转换成数组

2.tolist序列转换成list<t>

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
using system;
using system.collections.generic;
using system.linq;
using system.text;
 
namespace 立即执行的enumerable类方法成员
{
  class program
  {
    static void main(string[] args)
    {
      //1.toarray序列转换成数组
      list<string> names =new list<string> { "debuglzq","sarah","jerry","jeffrey","m&m"};
      string[] takenames = names.toarray();
 
      string[] takenames2 = (from name in names
                 where name.indexof("je")>-1
                 select name).toarray();
 
      //2.tolist序列转换成list<t>
      string[] namesa = { "debuglzq", "sarah", "jerry", "jeffrey", "m&m" };
      list<string> takenames_tolist = namesa.tolist();
      list<string> takenames_tolist2 = (from name in namesa select name).tolist();
 
      //
    }
  }
}

程序结果显而易见,所以没有写输出语句;
3.todictionary把序列转换为泛型dictionary<tkey,tvalue>

4.tolookup用于将序列转换为泛型lookup<tkey,tvalue>

dictionary和lookup是非常近似的一对类型,都通过“键”访问相关的元素,不同的是dictionary的key和value是一一对应关系,lookup的key和value是一对多关系,lookup没有公共构造函数,时能用tolookup构建,创建后也不能删除lookup中的元素。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
using system;
using system.collections.generic;
using system.linq;
using system.text;
 
namespace todictionary
{
  /// <summary>
  /// 3.todictionary把序列转换为泛型dictionary<tkey,tvalue>
  /// </summary>
  class program
  {
    static void main(string[] args)
    {
      list<guestinfo> glist = new list<guestinfo>()
      {
        new guestinfo(){name="jeffrey", age=33,tel="136********"},
        new guestinfo(){ name="debuglzq", age=25,tel="187********"},
        new guestinfo(){name="sarah", age=24,tel="159********"},
        new guestinfo(){name="jerry", age=33,tel="135********"},
        new guestinfo(){name="smith", age=33,tel="139********"}       
      };
      //todictionary把序列转换为泛型dictionary
      //todictionary重载了4个方法
      //a.用name作为dictionary的“键”,guest为“value”
      dictionary<string, guestinfo> dictionary1 = glist.todictionary(guest => guest.name);
      foreach (var s in dictionary1 )
      {
        console.writeline("键值{0}:{1} {2} {3}",s.key,s.value.name,s.value.age,s.value.tel );
      }
      console.writeline("--------------------------------");
      console.readkey();
      //b.自定义比较器     
      dictionary<string,guestinfo> dictionary2=glist.todictionary(guest=>guest.name,new myequalitycomparer<string>());
      foreach (var s in dictionary2)
      {
        console.writeline("键值{0}:{1} {2} {3}", s.key, s.value.name, s.value.age, s.value.tel);
      }
      console.writeline("--------------------------------");
      console.readkey();
      //c.用name作为dictionary的“键”,tel属性为"value"
      dictionary<string, string> dictionary3 = glist.todictionary(guest=>guest.name,g=>g.tel);
      foreach (var s in dictionary3)
      {
        console.writeline("键值{0}:{1}", s.key, s.value);
      }
      console.writeline("--------------------------------");
      console.readkey();
      //d.自定义比较器
      dictionary<string, string> dictionary4 = glist.todictionary(guest=>guest.name,g=>g.tel,new myequalitycomparer<string>());
      foreach (var s in dictionary4)
      {
        console.writeline("键值{0}:{1}", s.key, s.value);
      }
      console.writeline("------------------------------------------------------");
      console.readkey();
 
 
      ///////////////
      ///4.tolookup用于将序列转换为泛型lookup<tkey,tvalue>。
      ///dictionary和lookup是非常近似的一对类型,都通过“键”访问相关的元素,不同的是dictionary的key和value是一一对应关系
      ///lookup的key和value是一对多关系
      ///lookup没有公共构造函数,时能用tolookup构建,创建后也不能删除lookup中的元素。
      ///该方法也有4个原型,和上面的todictionary极像
      ///
      //a. name的第一个字符(字符串)作key
      ilookup<string, guestinfo> lookup1 = glist.tolookup(guest => guest.name.substring(0, 1));
      foreach (var k in lookup1)
      {
        console.writeline(k.key);//键值
        foreach (var v in k)
        {
          console.write("{0},{1},{2}",v.name,v.age,v.tel );
        }
        console.writeline();
      }
      console.writeline("--------------------------------");
      console.readkey();
      //b自定义比较器
      ilookup<string, guestinfo> lookup2 = glist.tolookup(guest => guest.name.substring(0, 1), new myequalitycomparer<string>());
      foreach (var k in lookup2)
      {
        console.writeline(k.key);//键值
        foreach (var v in k)
        {
          console.write("{0},{1},{2}", v.name, v.age, v.tel);
        }
        console.writeline();
      }
      console.writeline("--------------------------------");
      console.readkey();
      //c
      ilookup<string, string> lookup3 = glist.tolookup(guest=>guest.name.substring(0,1),g=>g.name );
      foreach (var k in lookup3)
      {
        console.writeline(k.key);//键值
        foreach (var v in k)
        {
          console.write("{0} ", v);
        }
        console.writeline();
      }
      console.writeline("--------------------------------");
      console.readkey();
      //d自定义比较器
      ilookup<string, string> lookup4 = glist.tolookup(guest=>guest.name.substring(0,1),g=>g.name,new myequalitycomparer<string>());
      foreach (var k in lookup4)
      {
        console.writeline(k.key);//键值
        foreach (var v in k)
        {
          console.write("{0} ", v);
        }
        console.writeline();
      }
      console.writeline("--------------------------------");
      console.readkey();
    }
  }
}

程序运行结果如下:

C#使用LINQ中Enumerable类方法的延迟与立即执行的控制

没有显示完全,后面一组输出和上面最后一组相同(只是使用了自定义的比较器)。

 5.sequenceequal 比较两个序列是否相等

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
using system;
using system.collections.generic;
using system.linq;
using system.text;
 
namespace sequenceequal
{
  /// <summary>
  ///
  /// </summary>
  class program
  {
    static void main(string[] args)
    {
      //5.sequenceequal 比较两个序列是否相等
      //a比较两个序列
      string[] names1 ={ "debuglzq","sarah","jerry","jeffrey","m&m"};
      list<string> names2 = new list<string> { "debuglzq", "sarah", "jerry", "jeffrey", "m&m" };
      bool equalornot = names1.sequenceequal(names2);
      bool equalornot2 = names1.skip(3).take(2).sequenceequal(names2.take(3).skipwhile(n=>n.length==3));
      console.writeline("{0},{1}",equalornot,equalornot2 );
      console.writeline("----------------------------");
      console.readkey();
      //b自定义比较器
      bool equalornot3 = names1.sequenceequal(names2, new myequalitycomparer<string>(names2.toarray()));
      console.writeline("{0}",equalornot3);
      console.readkey();
    }
  }
}

自定义的比较器如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
using system;
using system.collections.generic;
using system.linq;
using system.text;
 
namespace sequenceequal
{
  //debuglzq提示:
  //如不知道具体的接口实现
  //可以用vs提供的自动实现接口功能实现这个接口
  class myequalitycomparer<t> : iequalitycomparer<t>
  {
    private string[] sec;
    public myequalitycomparer(string[] s)
    {
      sec = s;
    }
    #region iequalitycomparer<t> 成员
 
    public bool equals(t x, t y)
    {
      string temp = x as string;
      if (x != null)
      {
        return sec.contains(temp);
      }
      return false;
    }
 
    public int gethashcode(t obj)
    {
      return obj.gethashcode();
    }
 
    #endregion
  }
}

可以使用vs自动实现接口的智能提示,完成接口的实现。
接口的实现方式有“实现接口”和“显式实现接口”之分,上面这种实现方式即“显示接口”方式,“显示实现接口”最显著的特征是实现的接口方法加了个完全限定名,这样显式实现之后,无法通过具体的类名来访问接口方法,只能通过接口名来访问,这样可以隐藏类的复杂性。

程序运行结果如下:

C#使用LINQ中Enumerable类方法的延迟与立即执行的控制

6.first 返回序列第一个满足条件元素

7.firstordefault 返回序列第一个满足条件元素,如果没有找到则返回默认值

8.last

9.lastordefault

10.single返回序列中唯一的元素,如果序列中包含多个元素,会引发运行错误!

11.singleordefault 找出序列中满足一定条件的元素,如果序列为空则返回默认值, 如果序列中包含多个多个元素会引发运行错误!!

12.elementat 获得指定索引处的元素

13.elementatordefault 获得指定索引处的元素,如果超出索引,则返回元素类型的默认值

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
using system;
using system.collections.generic;
using system.linq;
using system.text;
 
namespace first_firstordefault_last_lastordefault_elementat_elementatordefaul
{
  class program
  {
    static void main(string[] args)
    {
      //6.first
      string[] names = { "debuglzq", "sarah", "jerry", "jeffrey", "m&m" };
      var item = names.first();
      var item2 = names.first(n => n == "sarah");
      console.writeline("{0},{1}",item,item2 );
      console.readkey();
      //7.firstordefault
      var item3 = names.firstordefault();
      var item4 = names.firstordefault(n => n == "sarah");
      console.writeline("{0},{1}", item3, item4);
      console.readkey();
      //8.last
      var item5 = names.last();
      var item6 = names.lastordefault(n => n == "sarah");
      console.writeline("{0},{1}", item5, item6);
      console.readkey();
      //9lastordefault
      var item7 = names.lastordefault();
      var item8 = names.lastordefault(n => n == "sarah");
      console.writeline("{0},{1}", item7, item8);
      console.readkey();
      //10.single返回序列中唯一的元素,如果序列中包含多个元素,会引发运行错误!
      try
      {
        var item9 = names.single();
      }
      catch(exception ex)
      {
        console.writeline(ex.message);
      }
      //
      var item10 = names.single(n => n == "sarah");
      console.writeline("{0}",item10 );
      console.readkey();
      //11.singleordefault 找出序列中满足一定条件的元素,如果序列为空则返回默认值, 如果序列中包含多个多个元素会引发运行错误!!
      try
      {
        var item11 = enumerable.empty<string>().singleordefault();
        console.writeline("{0}",item11);//不报错,如果序列为空就返回默认值
      }
      catch (exception ex)
      {
        console.writeline(ex.message );
      }
      try
      {
        var item12 = names.singleordefault();
        console.writeline("{0}", item12);//报错,序列包含多行错误
      }
      catch (exception ex)
      {
        console.writeline(ex.message);
      }
      var item13 = enumerable.empty<string>().defaultifempty("debuglzq").singleordefault();
      console.writeline("{0}", item13);
      var item14 = names.singleordefault(n => n == "xxx");
      console.writeline("{0}", item14);
      console.readkey();
      //12elementat 获得指定索引处的元素
      var item15 = names.elementat(3);
      console.writeline("{0}", item15);
      console.readkey();
      //13elementatordefault 获得指定索引处的元素,如果超出索引,则返回元素类型的默认值
      var item16 = names.elementatordefault(3);
      var item17 = names.elementatordefault(100);
      console.writeline("{0},{1}",item16,item17);
      console.readkey();
    }
  }
}

程序运行结果如下:

C#使用LINQ中Enumerable类方法的延迟与立即执行的控制

14.all序列中的所有元素是否都满足条件

15.any序列中的元素是否存在或满足条件

16.contains确定元素是否在序列中

17.count序列包含元素的数量

18.longcount获取一个int64类型的元素数量

19.aggregate将序列元素进行累加

20.sum序列之和

21.average序列平均值

22.min序列的最小值

23.max序列的最大值

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
using system;
using system.collections.generic;
using system.linq;
using system.text;
 
namespace all_any_count_longcount_aggregate_sumaverage_min_max
{
  class program
  {
    static void main(string[] args)
    {
      string[] names = { "debuglzq", "sarah", "jerry", "jeffrey", "m&m" };
      //14all序列中的所有元素是否都满足条件
      bool b1 = names.all(s=>s.gettypecode()==typecode.string );
      bool b2 = names.all(s=>s.indexof("s")>-1);
      console.writeline("{0},{1}",b1,b2);
      console.readkey();
      console.writeline("----------------------");
      //15any序列中的元素是否存在或满足条件
      bool p1 = names.any();
      bool p2 = names.any(s => s.indexof("s")>-1);
      console.writeline("{0},{1}", p1, p2);
      console.readkey();
      console.writeline("----------------------");
      //16contains确定元素是否在序列中
      //a
      bool q1 = names.contains("mm");
      //b自定义比较函数
      bool q2 = names.contains("mm", new myequalitycomparer<string>());
      console.writeline("{0},{1}", q1, q2);
      console.readkey();
      console.writeline("----------------------");
      //17count序列包含元素的数量
      int i1 = names.count();
      int i2 = names.count(n => n.length == 5);
      console.writeline("{0},{1}", i1, i2);
      console.readkey();
      console.writeline("----------------------");
      //18longcount获取一个int64类型的元素数量
      long j1 = names.longcount();
      long j2 = names.longcount(n => n.length == 5);
      console.writeline("{0},{1}",j1, j2);
      console.readkey();
      console.writeline("----------------------");
      //19aggregate将序列元素进行累加
      int[] nums = { 10,20,30,40,50};
      int a1 = nums.aggregate((n1,n2)=>n1+n2);//150
      int a2 = nums.aggregate(50,(n1,n2)=>n1+n2);//200     
      console.writeline("{0},{1}", a1, a2);
      string s1 = names.aggregate((name1,name2)=>string.format("{0}、{1}",name1,name2));
      string s2= names.aggregate("the result is ",(name1, name2) => string.format("{0}、{1}", name1, name2));
      console.writeline("{0}", s1);
      console.writeline("{0}", s2);
      console.readkey();
      console.writeline("----------------------");
      //20sum序列之和
      int sum = nums.sum();
      //21average序列平均值
      double avg = nums.average();
      //22min序列的最小值
      int min = nums.min();
      //23max序列的最大值
      int max=nums.max();
      console.writeline("{0},{1},{2},{3}", sum, avg,min,max);
      console.readkey();
      
    }
  }
}

程序运行结果如下:

C#使用LINQ中Enumerable类方法的延迟与立即执行的控制

延伸 · 阅读

精彩推荐
  • C#利用C#实现网络爬虫

    利用C#实现网络爬虫

    这篇文章主要介绍了利用C#实现网络爬虫,完整的介绍了C#实现网络爬虫详细过程,感兴趣的小伙伴们可以参考一下...

    C#教程网11852021-11-16
  • C#C#微信公众号与订阅号接口开发示例代码

    C#微信公众号与订阅号接口开发示例代码

    这篇文章主要介绍了C#微信公众号与订阅号接口开发示例代码,结合实例形式简单分析了C#针对微信接口的调用与处理技巧,需要的朋友可以参考下...

    smartsmile20127762021-11-25
  • C#三十分钟快速掌握C# 6.0知识点

    三十分钟快速掌握C# 6.0知识点

    这篇文章主要介绍了C# 6.0的相关知识点,文中介绍的非常详细,通过这篇文字可以让大家在三十分钟内快速的掌握C# 6.0,需要的朋友可以参考借鉴,下面来...

    雨夜潇湘8272021-12-28
  • C#VS2012 程序打包部署图文详解

    VS2012 程序打包部署图文详解

    VS2012虽然没有集成打包工具,但它为我们提供了下载的端口,需要我们手动安装一个插件InstallShield。网上有很多第三方的打包工具,但为什么偏要使用微软...

    张信秀7712021-12-15
  • C#C#设计模式之Strategy策略模式解决007大破密码危机问题示例

    C#设计模式之Strategy策略模式解决007大破密码危机问题示例

    这篇文章主要介绍了C#设计模式之Strategy策略模式解决007大破密码危机问题,简单描述了策略模式的定义并结合加密解密算法实例分析了C#策略模式的具体使用...

    GhostRider10972022-01-21
  • C#SQLite在C#中的安装与操作技巧

    SQLite在C#中的安装与操作技巧

    SQLite,是一款轻型的数据库,用于本地的数据储存。其优点有很多,下面通过本文给大家介绍SQLite在C#中的安装与操作技巧,感兴趣的的朋友参考下吧...

    蓝曈魅11162022-01-20
  • C#深入理解C#的数组

    深入理解C#的数组

    本篇文章主要介绍了C#的数组,数组是一种数据结构,详细的介绍了数组的声明和访问等,有兴趣的可以了解一下。...

    佳园9492021-12-10
  • C#如何使用C#将Tensorflow训练的.pb文件用在生产环境详解

    如何使用C#将Tensorflow训练的.pb文件用在生产环境详解

    这篇文章主要给大家介绍了关于如何使用C#将Tensorflow训练的.pb文件用在生产环境的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考借鉴...

    bbird201811792022-03-05