C# 标准查询表达式

一、标准查询运算符

1、C#提供了标准查询运算符,例如我想选择专利一系列(pantents)中以年份19开头的专利,可以用如下语句:

            IEnumerable<Patent>  pantentWhere = pantents.Where(pantent => 
                                                                pantent.YearOfPublicaton.StartsWith("19"));

当然,此处的语句只是定义了查询,此时pantentWhere并没有内容,后面Lambda表达式指定的查询并没有执行,只有当遍历pantentWhere集合的时候才开始执行这个查询规则,这是C#中标准查询的“推迟执行”

2、投射

专利类包含了 名字  年份  应用号  发明者 等,如果我想将专利类的集合中 每个专利的类型都变为只包含 名字与年份的类型,那么可以使用select做到,代码如下:

1 var pantentSelect = pantents.Select(
2                 pantent => 
3                 { 
4                     return new 
5                     { 
6                         Title = pantent.Title, 
7                         Year = pantent.YearOfPublicaton 
8                     }; 
9                 });

可以看到,Lambda表达式返回了一个包含 名字与年份的类型。而当遍历pantentSelect时,其投射语句执行,它则是有[(姓名,值),(年份,值)]构成的集合。

3、排序

利用标准查询运算符OrderByDescending 与 ThenByDescending 可以完成多条件的排序,代码如下:

1 IEnumerable<Patent> pantentOrder = pantents.OrderByDescending(pantent => 
2                                                           pantent.YearOfPublicaton).ThenByDescending(
3                                                           pantent => pantent.Title);

可以看到,只用了一个OrderBy,它会获取并且只会获取一个成为KeySelector的参数来排序,例如本例中的YearOfPublicaton。如果要继续按照第二个关键字排序,只能用ThenBy,在OrderBy的基础上执行。而连着使用多个OrderBy只会撤销上一个OrderBy,所以要用ThenBy,而不是继续使用OrderBy。

此处仅仅简单的列出几项,因为如果执行比较复杂的查询与投射,将会产生比较繁琐难懂的代码。因此,C# 3.0中引入了标准查询表达式,一种更类似于SQL语言的

二、标准查询表达式

1、简单示例,下段代码完成的功能是检索出不含有*的单词:

 1 class Program
 2     {
 3         static string[] Keywords = { "*a", "*b", "*c", "*d", "*e", "*f", "a", "b", "c", "d", "e", "f", "g", "h", "i"};
 4         static void Main(string[] args)
 5         {
 6             ShowContextualKeyword1();
 7         }
 8         public static void ShowContextualKeyword1()
 9         {
10             IEnumerable<string> selection = from word in Keywords
11                                             where !word.Contains('*')
12                                             select word;
13             foreach (string s in selection)
14             {
15                 Console.WriteLine(" " + s);
16             }
17         }
18     }

值得详细说一下的是类型推断:select投射回的是word的集合,word的类型是from后面的那个word,从Keywords推断得到。Keywords是一个string的集合,所以word是string类型,因此select投射到的是IEnumerable<string>

 2、改变返回类型。

select不仅可以返回原始类型,也可以返回指定的类型,我个人总结的是 他会返回select后面的变量的集合类型。

如下代码,返回的不是fileName的集合,而是FileInfo的集合:

1   public static void List1(string rootDirectory, string searchPattern)
2         {
3             IEnumerable<FileInfo> files = from fileName in Directory.GetFiles(rootDirectory, searchPattern)
4                                           select new FileInfo(fileName);
5             foreach (FileInfo file in files)
6             {
7                 Console.WriteLine(".{0}({1})",file.Name,file.LastWriteTime);
8             }
9         }

 当然,3.0允许程序员不必显示声明投射的类型,而可以使用匿名类型,如下代码所示:

 1 public static void List2(string rootDirectory, string searchPattern)
 2         {
 3             var files = from fileName in Directory.GetFiles(rootDirectory, searchPattern)
 4                         select new 
 5                         {
 6                             Name = fileName,
 7                             LastWriteTime = File.GetLastWriteTime(fileName)
 8                         };
 9             foreach (var file in files)
10             {
11                 Console.WriteLine(".{0}({1})", file.Name, file.LastWriteTime);
12             }
13         }

如果select的原始数据的列特别多,改变投射类型则显得十分有优势,只需选出需要关注的几列即可,而不用全部都检索出来。

3、筛选(where)

筛选条件靠断言来表示,即返回布尔值的一个,真就接受,假就放弃。代码如下,功能是筛选出一个月之前修改的文件:

 1  static void FindMonthOldFiles(string rootDirectory, string searchPattern)
 2         {
 3             // 筛选出一个月之前访问的数据
 4             IEnumerable<FileInfo> files = from fileName in Directory.GetFiles(rootDirectory, searchPattern)
 5                                           where File.GetLastWriteTime(fileName) < DateTime.Now.AddMonths(-1)
 6                                           select new FileInfo(fileName);
 7             foreach (FileInfo file in files)
 8             {
 9                 string relativePath = file.FullName.Substring(3);
10                 Console.WriteLine(".{0}.({1})", relativePath, file.LastWriteTime);
11             }
12         }

4、排序

下面代码展示了一种排序:首先按照文件名长度降序排序,然后按照文件名升序排序(不显示声明升序还是降序的,默认升序):

 IEnumerable<string> fileNames = from fileName in Directory.GetFiles(rootDirectory,searchPattern)
                                            orderby (new FileInfo(fileName)).Length descending,fileName
                                            select fileName;

多个排序条件用逗号隔开,重要性依次降低。但是如果我想投射一个FileInfo的集合怎么办呢?可能会有如下代码:

1             IEnumerable<FileInfo> fileNames = from fileName in Directory.GetFiles(rootDirectory,searchPattern)
2                                             orderby (new FileInfo(fileName)).Length descending,fileName
3                                             select new FileInfo(fileName);

那么问题来了。看第2行与第3行,这样写会每一次访问,都会实例化两个FileInfo,十分浪费系统资源,于是C#3.0隆重推出了let字句。

5、let子句

let 子句添加的表达式可以在整个查询表达式的范围内使用,从而避免重复实例化,写法如下:

1 IEnumerable<FileInfo> fileNames = from fileName in Directory.GetFiles(rootDirectory,searchPattern)
2                                               let file = new FileInfo(fileName)
3                                               orderby file.Length descending, fileName
4                                               select file;

6、编译

实际上,使用查询运算符与查询表达式对CIL CLR没有影响,编译器会将查询表达式转化成标准查询运算符。虽然属于语法糖级别的,但是平时尽可能多使用查询表达式,除非在某些特定情况下,再使用标准查询运算符。

转载于:https://www.cnblogs.com/tntboom/p/4145235.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: C is a programming language that was originally developed in the 1970s by Dennis Ritchie at Bell Labs. It is a general-purpose, imperative programming language that is widely used for developing operating systems, system software, embedded systems, and other applications that require low-level access to hardware. C is a compiled language, meaning that code written in C is first translated into machine code by a compiler before being executed. This makes it a relatively fast language compared to interpreted languages like Python or JavaScript. C is known for its low-level features, including pointers and direct memory manipulation, which give developers fine-grained control over the behavior of their programs. This also means that C programs can be more prone to errors, such as buffer overflows or memory leaks, if not written carefully. C has influenced many other programming languages, including C++, Java, and Python. It remains a popular language for system programming, embedded systems, and other applications that require low-level control over hardware. ### 回答2: C 是计算机编程语言中的一种,它是一种通用的高级编程语言。C 语言由美国计算机科学家德尼斯·里奇在20世纪70年代开发出来,最初是为了编写操作系统UNIX而设计的。C 语言相对简单,但功能强大,可以用于开发各种软件和应用。 C 语言具有丰富的数据类型,如整数、浮点数、字符以及数组、结构等。它还有强大的控制结构,如条件语句、循环语句和跳转语句,使得程序的编写更加灵活。C 语言还支持函数的定义和调用,这样可以将程序分为多个模块,提高代码的可维护性。 C 语言的代码编写简洁,运行效率高,非常适合系统底层的开发。许多操作系统、编译器、数据库和嵌入式系统等都是用C语言编写的。C 语言也是很多编程新手的入门语言,因为它的学习曲线相对较低,但掌握 C 语言的基础知识对于学习其他编程语言非常有帮助。 C 语言是一种面向过程的语言,较为底层,需要程序员手动管理内存。为了降低内存管理的负担,后来又出现了C++语言,它是在 C 语言的基础上增加了面向对象的特性,使得编程更加高级和简化。但是,C 语言仍然被广泛使用,特别是在嵌入式系统、驱动程序和核心开发等领域。 总之,C 语言是一种重要的编程语言,具有简洁高效、灵活多样的特点,广泛应用于计算机科学和软件开发领域。掌握 C 语言可以为进一步学习其他编程语言打下良好的基础。 ### 回答3: C是计算机科学领域重要的编程语言之一,它由美国贝尔实验室的Dennis Ritchie开发。C语言于1972年首次发布,之后逐渐流行并成为了广泛应用的编程语言。C语言的设计目标是提供一种直接的、可移植的编程语言,用来开发高效的系统软件和应用程序。 C语言具有很多特点。首先,C语言是一种结构化的编程语言,它通过使用函数和块来组织代码,使程序的结构更加清晰和可读。其次,C语言具有丰富的运算符和表达式,可以进行复杂的数学运算和逻辑判断。另外,C语言具备高度的可移植性,可以在不同的硬件平台上编译和运行。 C语言还具有丰富的标准库函数,可以方便地实现诸如文件操作、字符串处理、内存管理等功能。此外,C语言还支持指针操作,允许直接访问和操作内存地址,提高程序的效率。 在计算机科学领域,C语言被广泛应用于系统软件的编写,如操作系统、编译器等。同时,C语言也是许多高级编程语言的基础,如C++、Java等,因此熟练掌握C语言将有助于学习和理解其他编程语言。 总而言之,C语言作为计算机科学领域的一种重要编程语言,具有结构化、高效、可移植的特点,被广泛应用于系统软件和应用程序的开发。对于学习和理解计算机科学的基本原理和概念来说,掌握C语言是非常重要的。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值