Linq学习笔记(转)

开始Linq前你要知道的

  扩展方法

  顾名思义就是对现有类进行扩展的的方法,扩展方法可以在不修改现有类的情况下,为现有类增加公共的接口(不是C#中的interface)。

  扩展方法本质上是一个静态方法,不同之处在于它的第一个参数必须有this关键字声明,并且第一个参数的类型即为要扩展的类型。如

public static double ToDouble(this string source)
{double res = 0d;double.TryParse(source, out res);return res;
}public static void SimpleExtesionMethod()
{double d = "12345.54321".ToDouble();Console.WriteLine(d);
}

这里是个简单的将字符串转为double类型的扩展方法,只要引用了该方法的命名空间,则都可以直接用string类型来调用ToDouble方法。

  扩展方法是后文的基础,C#3.0中的Linq的实现都是基于扩展方法,通过对IEnumerable<T>接口(Linq to Objects)的扩展和对IQueryable<T>的扩展来实现Linq的相关功能,而Linq的相关关键字最终都是转化为对IEnumerable<T>(IQueryable<T>)的调用。

  Lambda表达式

  lambda表达式其实就是.net2.0中的匿名方法,然后再3.0中以一种更优美的姿态呈现出来。

  lambda表达式的基本语法为

  (参数列表) =>{语句块;}    或者  ( 参数列表) =>表达式

  当参数列表中只有一个参数的时候,圆括号可以省略

Func<string, string> func = x => x + x;
Console.WriteLine(func("a")); 

Var:隐式类型化变量

  使用与可以由编译器推导出的变量的声明,不需要显式指定对象的类型。

var container = new List<string> { "张三", "李四", "王五" };
IEnumerable<string> query = from name in containerselect name;

 

上例中由于定义中已经指明了对象的类型,声明中已经完全没有必要使用显示的类型定义,所以可以使用var关键字。

  对于匿名对象

var test = new { Name = "Sth.", Type = "UnKnown" };

由于无法用一个类型类声明匿名对象,此时可以用var是声明。

  注意var只是省下了显式声明的过程,而C#本身就是静态语言,所以var所声明的变量的类型已经确定任然是不能改变的,亦即,var并非是变体类型。

Linq对谁适用

  linq的语法通过System.Linq下面的Enumerable类提供支持,通过观察他的签名,你就会发现他为IEnumerable<T>实现了一系列的扩展方法,也就是说,只要是实现了IEnumerable<T>的对象都可以使用Linq的语法来查询

  而对于只实现了IEnumerable接口而没有实现IEnumerable<T>的对象可以通过

 

public static IEnumerable<TResult> Cast<TResult>(this IEnumerable source);

 

来将IEnumerable接口转为IEnumerable<T>(例如ArrayList)。

Linq中的关键字

  在C#3.0中,为Linq引入了一些新的关键字,他们是:

  from join where group into let orderby select

  熟悉Sql的同学看着是不是有些眼熟呢,其实在Linq中他们的涵义和在SQL中类似的,所以会很容易理解的。接下来的时间,简单介绍下这些关键字的使用。

from

  from子句是一个Linq查询的开始,任何一个Linq语句都是以from开始,from子句指定查询的容器,和在此语句有效的局部变量(用来指定容器中的一项,from子句的效果很类似于foreach)。from子句的语法为

 from local in container

local就是在此Linq语句中的局部变量,由于container必须为IEnumerable<T>,他的类型可以由container推导出来(即T)。上一段简单的例子:

ar container = new List<string> { "张三", "李四", "王五" };
var query = from name in containerselect name;foreach (string name in query)
{Console.WriteLine(name);
}

输出:

张三
李四
王五

如果container仅仅实现IEnumerable而没有实现IEnumerable<T>,则需要显式指定局部变量的类型,或者是使用Cast转为IEnumerable<T>

var container = new ArrayList { "张三", "李四", "王五" };
var query = from name in container.Cast<string>()select name;
//或者
var query1 = from string name in containerselect name;

select

  对查询的结果进行投影,在子句中指定要选择的列,如上例。有的时候,我们只需要投影某一列,我们可以这样

private static void TestSelectSingleProperty()
{var persons = GetPersons();var query = from p in personsselect p.Name;foreach (var item in query){Console.WriteLine(item);}
}

我们还可以指定要投影的列的集合,这个时候我们要用到匿名类型

var query = from p in personsselect new { p.ID, p.Name };foreach (var item in query)
{Console.WriteLine("No:{0},Name:{1}",item.ID,item.Name);
}

query中的每一项都时候一个拥有ID属性和Name属性的对象,当然有的时候实体的属性名不是我们想要的,或者是通过对属性计算得来的,那么我们可以显式指定属性名,就像下面这样:

var query = from p in personsselect new{UserID = p.ID,FriendName = p.Gender == "" ? "Mr" : "Ms" + p.Name};foreach (var item in query)
{Console.WriteLine("No:{0},Friendly Name:{1}", item.UserID, item.FriendName);
}

where

  对容器内的数据进行筛选。

var query = from p in personswhere p.DepartmentID == 1select p.Name;

join

  类似SQL里的join,Linq中的join子句用于将两个容器的数据以某种关系进行关联。

var departments = GetDepartments();
var persons = GetPersons();var query = from d in departmentsjoin p in persons on d.ID equals p.DepartmentIDselect new { d, p };

值得注意的是join子句只能使用equals或者是not equal而不能用其他运算符(==都不行)而equals运算符左边必须联接的左部,右边为右部,不能调换的,否则编译不能通过。

into

  into子句用于将join或者是group子句的结果进一步持续化,包装成为一个

  System.Linq.IGrouping<TKey, TElement>对象,

  而且IGrouping继承自IEnumerable<TElement>,可以看出,IGrouping接口提供分组的键和,该键下所包含的集合。例子见group

group

  对结果按照指定的条件进行分组

var container = new List<string> { "ZhangSan", "LiSi", "Wangwu", "ZhaoLiu", "Deng" };
var query = from name in containergroup name by name.Length into gselect new { g.Key, Values = g };

例子演示了通过姓名的长度对一个姓名列表进行分组,并将分组的结果保持到局部变量g中,可以通过下面的代码将query的结果输出

foreach (var group in query)
{Console.WriteLine("{0}:", group.Key);foreach (var item in group.Values){Console.WriteLine(item);}
} 

let

  let子句用于在查询中添加一个新的局部变量,使其在后面的查询中可见

var query = from p in personslet friendlyName = p.Gender == "" ? "Mr" : "Ms" + p.Nameselect new{UserID = p.ID,FriendName = friendlyName};foreach (var item in query)
{Console.WriteLine("No:{0},Friendly Name:{1}", item.UserID, item.FriendName);
}

在IEnumerable<T>上的其他扩展

  Take Skip

  用于选取前XX个或者和跳过前XX个,如选择第11到20个则可以

query.Skip(10).Take(10);

OrderBy OrderByDescending

  排序而已

query.OrderBy(c => c.Length);

Distinct Union Intersect Except 这些单词都见过吧,分别就是取不重复,并集,交集,差集(这个貌似看看参数就明白了)

  其他扩展都在Enumerable类下面了。

  Linq的延迟加载特性

  Linq查询的执行结果是IEnumerable<T>类型,而对IEnumerable<T>,在内部,C#通过yield关键字实现迭代器达到延迟加载的目的。从而使Linq查询只是在需要的时候才会被执行。

  但是,某一些扩展方法在执行时会试图遍历整个容器,从而使延迟加载无效,如排序,聚合函数(Count,Sum,Average等。)

static IEnumerable<int> InfinityInts()
{int count = 0;while (true)yield return count++;
}public static void LazyLoad()
{var query = from i in InfinityInts()select i;foreach (var i in query.Take(20)){Console.WriteLine(i);}
}public static void CantDoLazyLoad()
{var query = from i in InfinityInts()select i;foreach (var i in query.OrderBy(i => i).Take(20)){Console.WriteLine(i);}
}

这里有个简单的例子来证明,当使用Take时候,Linq语句能正常的执行,而当我们再Linq上使用一个Order By之后,程序就卡死了,当然,这是理所应当的,在失去延迟加载的特性之后,试图对一个无穷序列排序的结果一定是outOfMemory。

 

转载于:https://www.cnblogs.com/alsf/p/5993432.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/372150.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

cass展点不在原位置,cass中打开一副图后,通过绘图处理-——展高程点,怎么之前的图形就不显示了,,只剩下高程点!!...

答&#xff1a;1、进入控制面板&#xff0c;选择“卸载或更改程序”。 2、选中“AutoCAD2006”图标。 3、右击选择“更改”。 4、进入“AutoCAD2006安装程序对话框”&#xff0c;选择“添加/删除功能”单选按钮&#xff0c;点击下一步。 5、在“程序文件”列表中&#xff0c;选…

(二)windows下安装PHPCMS V9

一、准备工作 搭建环境 &#xff1a;参考:Windows下搭建PHP开发环境及相关注意事项PHPCMS V9 &#xff1a;下载适合自己 PHPCMS V9 版本到本地或服务器&#xff0c;下载地址&#xff1a;http://www.phpcms.cn/html/download/说明&#xff1a;官方提供了 2 种不同的编码。包括 G…

JavaFX 2.0布局窗格– HBox和VBox

如果要对JavaFX 2.0中所有不同的布局窗格进行概述&#xff0c;或者想了解有关它们的一些基本知识&#xff0c;请参阅我以前的文章《 JavaFX 2.0中的布局窗格》 。 布局窗格HBox和VBox绝对是JavaFX 2.0中最基本的布局容器。 如您所知&#xff0c;它们的用途是将所有子级布置在一…

flask mysql分页,Flask分页的实现方法

所需环境Flask-SQLAlchemy分页使用Flask-SQLAlchemy提供的pagination()方法。页数是pagination()方法的第一个参数&#xff0c;也是唯一必须的参数。可选参数per_page用来指定每页显示的记录数。参考代码&#xff1a;def index():# ...page request.args.get(page, 1, typeint…

Java中的生成器设计模式

Java 中的 Builder设计模式是一种创建模式&#xff0c;即用于创建对象&#xff0c;类似于 工厂方法设计模式 &#xff0c;这也是创建设计模式。 在学习任何设计模式之前&#xff0c;我建议先找出特定设计模式要解决的问题。 众所周知&#xff0c; 必要性是发明的母亲。 在没有面…

验证码( 随机数)

方式一&#xff08;变色版&#xff09;&#xff1a; <html> <head><meta charset"UTF-8"/><title></title><script src"jquery-2.0.2.min.js"></script> </head> <body> <?php header("co…

单片机串行通信全解析

1.什么是串行通信&#xff1f; 串行通信&#xff08;英语&#xff1a;Serial communication&#xff09;是指在计算机总线或其他数据通道上&#xff0c;每次传输一个位元数据&#xff0c;并连续进行以上单次过程的通信方式。与之对应的是并行通信&#xff0c;它在串行端口上通过…

java type 类型,java中的泛型类型与Type接口

假设我们定义了一个Room的类&#xff0c;表示一个房间public classRoom(){}由于我们建造好房间是&#xff0c;不知道房间以后的用途&#xff0c;他可能用来住人&#xff0c;也有可能用来放货物&#xff0c;因此需要用到泛型。但是我们可能想获取Room这个房间里面进来的的东西的…

centos7下操作防火墙

引言 最近使用centos7系统比较频繁&#xff0c;在配置服务器的时候&#xff0c;总是遇到能够ping通服务器&#xff0c;但是就是没有办法访问80端口&#xff0c;这个时候我的直觉告诉我&#xff0c;肯定是防火墙的原因&#xff0c;但是使用iptables却怎么都找不到命令&#xff0…

其他团队对本团队评价的总结

我们小组在看了其他小组的评价后&#xff0c;对自己的程序有了新的看法。转载于:https://www.cnblogs.com/bk1246788/p/6879691.html

Java:使用Fork / Join框架的Mergesort

此项的目的是显示一个Fork / Join RecursiveAction的简单示例&#xff0c;而不是过多地研究合并合并的可能优化方法&#xff0c;或者比使用Exkutor / Join Pool优于现有的基于Java 6的现有实现&#xff08;例如ExecutorService&#xff09;的相对优势。 以下是使用Java的自上而…

php的异常处理方式,php异常处理基本方法

当一个php脚本运行时&#xff0c;为了防止脚本运行崩溃&#xff0c;亦或是当php作为webserver&#xff0c;为了防止php程序出错&#xff0c;抛出httpcode500错误&#xff0c;我们常常需要对php程序做异常处理。今天介绍的是最基本的异常处理方法&#xff1a;一般而言&#xff0…

关系型数据库的三范式

第一范式:确保每列的原子性. 如果每列(或者每个属性)都是不可再分的最小数据单元(也称为最小的原子单元),则满足第一范式. 例如:顾客表(姓名、编号、地址、……)其中"地址"列还可以细分为国家、省、市、区等。第二范式:在第一范式的基础上更进一层,目标是确保表…

vray学习笔记(3)-多维子材质是个什么东西

多维子材质是个什么东西&#xff1f;为什么出现这个概念&#xff1f; 在3dsmax官方网站&#xff0c;我们可以看到它的定义&#xff1a; The Multi/Sub-Object material lets you assign different materials at the sub-object level of your geometry. 意思是多维子材质这个概…

Hello JavaFX 2.0:命令行介绍

我从博客文章Hello JavaFX 2.0&#xff1a;NetBeans 7.1 beta的介绍中&#xff0c;从NetBeans 7.1 beta的角度看了一个无处不在的Hello World示例的简单JavaFX版本。 在本文中&#xff0c;我将介绍仅使用命令行工具通过JavaFX实现的Hello World版本。 JavaFX 2.0 API文档包括ja…

matlab空格会消失了,如何在Matlab中自动删除保存的尾随空格?

我有同样的需求,并写了一个小脚本来做一些接近的事情.将以下内容放在MATLAB desktop shortcut中.每当您单击快捷方式按钮时,它将从编辑器中的活动文件中删除尾随空格.不如在保存时自动执行它 – 你需要记住在保存之前按下按钮 – 但差不多.测试在11b,12a和13b,但在12b也应该没问…

object to 字符串json

1 package com.beijxing.TestMain;2 3 import com.beijxing.entity.Student;4 import com.google.gson.Gson;5 import com.google.gson.annotations.SerializedName;6 7 /** 8 * 9 * author 作者 : ywp 10 * version 创建时间&#xff1a;2016年10月30日 下午9:21:33 11 */ 12…

JS 对象(Object)和字符串(String)互转

var jsObj {}; jsObj.testArray [1,2,3,4,5]; jsObj.name CSS3; jsObj.date 8 May, 2011; var str JSON.stringify(jsObj); var str1 JSON.parse(str); var str2 JSON.stringify(str1);alert(str);alert(str1); alert(str2);对象拷贝&#xff1a;var newObj JSON…

php 后退按钮事件,php – 后退按钮的会话问题

我在php文件中有这个代码,它包含在我要共享的所有页面中并保护我的页面.session_name("login");session_start();if (!isset($_SESSION[UserId])) {if(!header("Location: https://subdomain.mywebsite.com/")){ die("Unauthorized access"); }}…

异常:java lang AbstractMethodError

通常在尝试调用抽象方法时抛出此java.lang.AbstractMethodError。通常&#xff0c;此错误是在编译时本身识别的&#xff0c;如果在运行时抛出此错误&#xff0c;则该类必须不兼容&#xff08;与先前存在的类不兼容&#xff09; &#xff09;更改。因此&#xff0c;它是Incompat…