作为一个业余开发,断断续续学.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. Thinking in scala (1)----类

    ChecksumAccumulator.scala import scala.collection.mutable.Map class ChecksumAccumulator { private va ...

  2. Tsinsen-1487:分配游戏【树状数组】

    首先一定要看到x + y + z = N这个条件,没看到就世界再见了. 赢的人得分需要大于等于2,那么无非就是 (x, y), (x, z), (y, z), (x, y, z) 大于其他的点.但是考 ...

  3. .net面试题【持续更新.....】

    1.C#中readonly和const的区别? 2.C#中的排序继承自哪个接口?Icompare 3.阐述单点登录的实现原理? 4.C#中property和Attribute的区别? 5.Datase ...

  4. gulp学习指南之CSS合并、压缩与MD5命名及路径替换

    1.引入插件 var gulp = require('gulp'), // uglify = require('gulp-uglify'), concat = require('gulp-concat ...

  5. arcgis 瓦片图加载规则(转载)

    arcgis 瓦片图加载规则 最近需要做地图离线的功能,要能下载指定区域的瓦片图,我们都知道如何加载谷歌和天地图的加载规则,但是网上貌似没有找到如何加载arcgis自己发布的瓦片图规则,好不容易找到一 ...

  6. 在 AngularJS 中将 XML 转换为 JSON

    在这篇文章中,我们将谈谈如何在Angular JS中将XML文件转换为JSON.大家都知道Angular JS是开发应用程序的JavaScript框架.所以基本上Angular  JS期望得 到的响应 ...

  7. ImageView及其子类(三)

    实例:使用QuickContactBadge关联联系人      QuickContactBadge继承了ImageView,因此它的本质也是图片,也可以通过android:src属性指定他显示的图片 ...

  8. Android中的AutoCompleteTextView的使用

    最终的效果如下: main.xml代码如下: <?xml version="1.0" encoding="utf-8"?> <LinearLa ...

  9. 外部IIS/Apache/Nginx来代理FMS的http服务

    默认FMS在安装的时候,会安装Apache2.2,并监听8134端口,代理http服务器:当如也可以用外部的服务器,此时建立站点,并指向目录:C:\Program Files\Adobe\Flash ...

  10. jQuery获取URL中所带参数的办法

    可以使用正则表达式进行结果的拆分: http://www.cnblogs.com/babycool/p/3169058.html 可以直接进行所需内容的split: http://blog.scien ...