作为一个业余开发,断断续续学.net/c#也有不少日子了,

学习过程中,不断忘了学,学了忘,这让我很苦恼。

以前学习过程中,我总是在笔记本中记录下来知识要点,这么久下来,笔记本都写了四五本了。

然而,随着笔记本的增多,自己很快发现,笔记写了跟没写一样:笔记多了就找不到了……

所以,我觉得还是上博客园写博客,记录自己每天的学习心得。

如果有什么错误的地方,欢迎大神指教,小弟在这给大神跪谢了

============================================================

Linq入门篇

前篇:

    一直以来我都没接触过EF,因为我觉得它涉及到linq等乱七八糟的东西,还不如用原生ado.net舒服。最近想开了,大胆得尝试EF,那么就向着原先最头疼的linq攻关。

  我想很多人肯定跟我一样,第一次接触linq的时候,被linq,特别是它那些什么where 、order by子句弄得一脸懵逼。 我向来喜欢刨根寻底,对于那些只知其然不知其所以然的东西,我总是觉得浑身不舒服,这也是阻碍我学习linq的最大障碍。

  问题在于:这个语法到底是怎么回事?这些子句到底有什么联系?

解释:

    linq,书面解释就是Language Integrated Query,语言集成查询。单从字面上和百度百科上的解释,对于我等新手来说,看了恐怕只会更加懵逼,我想写这些的人他们是站在他们已经懂了的立场上写的解释,而不是我们这些不懂的人的立场。

    

   (一)从新手角度来说,要弄懂linq,首先就从以前如何查询集合入手。        关键词:委托    ------------------------如果不知道委托是啥,很简单的一句话可以理解委托:它就是一个存方法的类型。你可以借助委托把方法当做变量传递。

      我们假定有这样一个person类和 person类型 标识符为“persons”的泛型集合。 

  

public  class Person
{
public string Age{get;set;}
public string Name{get;set;}
public string Add{get;set;}
} public class Program
{
public void Main()
{
List<Person> persons=new List<Person>();
persons.Add(new Person(){Age=,Name="张三",Add="成都"});
persons.Add(new Person(){Age=,Name="李四",Add="成都"});
persons.Add(new Person(){Age=,Name="王五",Add="重庆"});
persons.Add(new Person(){Age=,Name="路人",Add="香港"});
}
  
}

      这样一个list泛型集合中,我们要查询这个集合里面,所有对象的ADD属性为“成都”的对象。传统的查询办法之一就是调用 persons.FindAll(委托参数) 方法。

    public void Main()
{
List<Person> persons=new List<Person>();
persons.Add(new Person(){Age=,Name="张三",Add="成都"});
persons.Add(new Person(){Age=,Name="李四",Add="成都"});
persons.Add(new Person(){Age=,Name="王五",Add="重庆"});
persons.Add(new Person(){Age=,Name="路人",Add="香港"}); /*chengduPerson是所有Add为成都的集合,找出persons集合中所有地址为成都的Person*/
List<Person> chengduPerson=persons.FindAll(p=>p.Add="成都"); }

      我们用反编译工具点开FindAll()方法看看他们到底是怎么回事呢?

//List<>集合的FindAll的源码

[__DynamicallyInvokable]
public List<T> FindAll(Predicate<T> match) //参数是一个泛型委托 这个委托要求方法传递一个集合元素类型的参数,返回一个BOOL值。具体说明在下面
{
if (match == null)
{
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.match);
}
List<T> list = new List<T>();
for (int i = ; i < this._size; i++)
{
if (match(this._items[i])) //借助match 来判断,传递过来的集合元素是否匹配,如果匹配就加入新的集合中。
{
list.Add(this._items[i]);
}
}
return list;
} //参数 Predicate<T> match 的委托声明如下
namespace System
{
// 摘要:
// 表示定义一组条件并确定指定对象是否符合这些条件的方法。
//
// 参数:
// obj:
// 要按照由此委托表示的方法中定义的条件进行比较的对象。
//
// 类型参数:
// T:
// 要比较的对象的类型。
//
// 返回结果:
// 如果 obj 符合由此委托表示的方法中定义的条件,则为 true;否则为 false。
public delegate bool Predicate<in T>(T obj);
}

        原来list集合就是借助委托来实现查询对象的。

  

   (二)list集合只是.net中众多集合中的一种,List<>我们可以用FindAll,那其他集合呢?我们可不可以有什么办法让他们都能用一个通用的方法呢?  有! 关键词:扩展方法  IEnumerable<>

              (1) 扩展方法是.net3.0的特性  它的具体语法就是在某个静态类的一个静态方法中第一个参数添加一个(this T name) T是期望添加到的类型。

public static class Test
{
public static void NewFunc(this string s)
{………}
} //将NewFunc添加到字符串对象中,字符串都可以调这个方法。扩展放方法其实并不是真正的给类型加方法,还是有区别的

      (2)IEnumerable<>接口是实现遍历的接口,基本上如list<>、 Dictionary<>等泛型集合都实现了这个接口,与之对应的,非泛型版的集合则实现的是IEnumerable接口

        明白这两点,我们就理解得出一个办法,我们要实现这样一个通用的集合查询。我们要实现使所有集合都可以通用一个方法进行查询,我们可以单独定义一个静态类,给IEnumerable、IEnumerable<>加扩展方法。使所有实现了          IEnumerable、IEnumerable<>的对象都可以调用这两个方法。

 public static IEnumerable<TResult> Select<TSource, TResult>(this IEnumerable<TSource> source, Func<TSource, int, TResult> selector)
{
}

      借助扩展方法和扩展方法  IEnumerable接口就可以实现所有集合都能调取查询方法。

    (三)重点来了----Linq    关键词 Enumerable 静态类。

      事实上,微软就是这样做的,在namespace System.Linq命名空间下,有一个叫Enumerable的静态类,它定义了WHERE、SELECT、OrderBy等方法,他们都是扩展方法,全部扩展给IEnumerable;

        [__DynamicallyInvokable]
public static IEnumerable<TResult> Select<TSource, TResult>(this IEnumerable<TSource> source, Func<TSource, int, TResult> selector)
{
if (source == null)
{
throw Error.ArgumentNull("source");
}
if (selector == null)
{
throw Error.ArgumentNull("selector");
}
return SelectIterator<TSource, TResult>(source, selector);
} private static IEnumerable<TResult> SelectIterator<TSource, TResult>(IEnumerable<TSource> source, Func<TSource, int, TResult> selector)
{
int iteratorVariable0 = -;
foreach (TSource iteratorVariable1 in source)
{
iteratorVariable0++;
yield return selector(iteratorVariable1, iteratorVariable0);
}
}
/*Enumerable 类中SELECT方法的源码*/ 需要注意,这里有个yield关键字,它的存在,使得这个查询会推迟到集合被遍历的时候才会执行

      微软定义这样一个类,给我们提供了一个巨大的便利,这其实就是Linq的最核心的东西。 而诸如一些简写的子句 例如 from XXX in XXX where XXX.XXX>XXX select XXX  这些WHERE、SELECT子句,实际上就是对这些方法的映射               的语法糖。

      如此一来,我们对Linq就有了一个最基本的了解。通过查看元数据,我们就可以知道我们可以对集合进行怎样的操作。为日后更深入的学习和应用打下良好的基础。

结语:

    实现Linq,用到了委托、多态、扩展方法等C#和面向对象的特性。通过对Linq的学习,再次让我感受到了设计之美。真是受益匪浅。

参考:C#高级编程第11章 Linq

新注册第一帖----------------------乱码新手自学.net 之Linq 入门篇的更多相关文章

  1. 2017年2月28日-----------乱码新手自学.net 之特性与验证

    现在看asp.net MVC5自学已经到了第六章:数据注解与验证. 话得从以前看MVC music store(音乐商店项目)的源码说起, 最初看music store源码完全就是一脸懵逼,整个程序, ...

  2. 2017年2月22日-----------乱码新手自学.net 之Entity Framework 增删改

    由于我是自学的,没有人教,在网上查资料也查不到个所以然.问大神们也是爱理不理的. 所以这篇随笔纯粹源自于我自己的认识.是否真正正确我也没有把握. 如果有什么错误,请大神们给予指正 ========== ...

  3. 2017年2月16日-----------乱码新手自学.net 之MVC模型

    第二篇博文,最近学习的内容还是回到了正题:ASP.NET MVC5之上.虽然EF学了个一知半解,但是用这点知识,看MVC5的MODEL部分应该还是够了.尽管周末还要恶补一下EF才行. (一)MVC简述 ...

  4. 2017年3月14日-----------乱码新手自学.net 之Authorize特性与Forms身份验证(登陆验证、授权小实例)

    有段时间没写博客了,最近工作比较忙,能敲代码的时间也不多. 我一直有一个想法,想给单位免费做点小软件,一切思路都想好了,但是卡在一个非常基础的问题上:登陆与授权. 为此,我看了很多关于微软提供的Ide ...

  5. 新注册域名greenopen.site,向专业道路进军

    新注册域名greenopen.site,向专业道路进军,欢迎访问!届时可以通过 greenopen.site jsxyhelu.github.io 或者jsxyhelu.cnblogs.com 访问本 ...

  6. wordpress新注册用户或重置密码链接失效

    在网上找了好多个博客,一个比一个不要脸,要更改的是两个文件,最后都抄成一个文件了. 原文链接https://www.cnblogs.com/liudecai/p/6474611.html 我是按照这个 ...

  7. Pycharm新手教程,只需要看这篇就够了

    pycharm是一款高效的python IDE工具,它非常强大,且可以跨平台,是新手首选工具!下面我给第一次使用这款软件的朋友做一个简单的使用教程,希望能给你带来帮助! 目前pycharm一共有两个版 ...

  8. Google C++测试框架系列入门篇:第二章 开始一个新项目

    上一篇:Google C++测试框架系列入门篇:第一章 介绍:为什么使用GTest? 原始链接:Setting up a New Test Project 词汇表 版本号:v_0.1 开始一个新项目 ...

  9. 01.普通抖音新手如何从0开始入门3个月做到粉丝100w+

    普通抖音新手如何从0开始入门3个月做到粉丝100w+ 今年以来,明显感觉抖音很火,大有干掉微信,取代淘宝,京东的感觉,如今年轻人,一周7天有7天要玩抖音,所以说未来不可估量. 如是,2019春节以后, ...

随机推荐

  1. ui主线程控件的更新就让这个activity的异步任务做完整

    项目中使用的SingleMessageView,控件实例化后,点击用户头像,此时跳转到UserInfo里查看这个用户的头像.用户名.签名.标签. 之前,师兄在SingleMessage里写了个头像的点 ...

  2. C#创建datatable (转)

      C#创建datatable 方法一: DataTable tblDatas = new DataTable("Datas"); DataColumn dc = null; dc ...

  3. ubuntu16.04 安装搜狗输入法

    刚刚升级ubuntu16.04LTS,安装搜狗输入法又出问题. 和以前一样,在官网下了deb包,直接双击安装,打开了Software Center(如下:改版过了,但是看起来是没有安装上的),点Ins ...

  4. php短数组写法

    在php 5.4+的版本中,可以使用  []  来表示  array() 例子: // On PHP 5.1 $data = array("foo", "bar" ...

  5. lufylegend库 LGraphics

    lufylegend库 LGraphics <!DOCTYPE html> <html lang="en"> <head> <meta c ...

  6. php之 有点复杂的 流程管理

    1.流程管理的用法是什么样的? 2.怎么发起想要的流程? 3.审批的人要是怎么审批通过? 4.流程审核是不是要挨个走过? 一.还是要有数据库的内容的 肯定会有表的,首先就是用户表了,然后就是流程表,用 ...

  7. linux下安装TensorFlow(centos)

    一.python安装 centos自带python2.7.5,这一步可以省略掉. 二.python-pip pip--python index package,累世linux的yum,安装管理pyth ...

  8. selenium相关面试题

    selenium中如何判断元素是否存在? selenium中hidden或者是display = none的元素是否可以定位到? selenium中如何保证操作元素的成功率?也就是说如何保证我点击的元 ...

  9. 【java设计模式】之 抽象工厂(Abstract Factory)模式

    1. 女娲的失误 上一节学习了工厂模式,女娲运用了该模式成功创建了三个人种,可是问题来了,她发现没有性别--这失误也忒大了点吧--竟然没有性别,那岂不是--无奈,只好抹掉重来了,于是所有人都被消灭掉了 ...

  10. gcc 简单编译流程

    注意:GCC在链接时优先使用动态链接库,只有当动态链接库不存在时才考虑使用静态链接库,可在编译时加上-static选项,强制使用静态链接库. gcc -static  此选项将禁止使用动态库,所以,编 ...