• 30分钟LINQ教程的学习笔记


     原文章 : http://www.cnblogs.com/liulun/archive/2013/02/26/2909985.html

    一、11个与LINQ有关的语言特性:
    【隐式类型、匿名类型、对象初始化器】、【自动属性】、【委托、泛型、泛型委托】、【匿名方法、Lambda表达式——匿名方法的简化写法】、【扩展方法——对接口也生效、迭代器】
    
    1. 隐式类型 var num = 1;
    2. 匿名类型 var obj = new {id=1,name="aa"};
    3. 对象初始化器
        var myObj = new MyObj(){id=1, name="aa"};
    ----------------------------------------------------------------
    4. 自动属性
        public string Title {get; set;}
    ----------------------------------------------------------------
    5. 委托:委托是一种类型
        delegate bool MoreOrLessDelgate(int item);
    
        委托类型,和类是一个级别的,它定义了某种方法规范。
        委托对象,和对象是同级别的,它指向某个方法。
        委托对象在使用时,实际上调用的是它指向的方法。
    6. 泛型:避免装箱拆箱操作时的类型转化的性能损耗。
        预定义的泛型类型
            List<T>
            Dictionary<TKey, TValue>
        自定义泛型类型
            public class SomeFac<T>
            {
                public T();
    
                public static T Instance()
                {
                    return default(T);
                }
            }
        自定义泛型类型时的泛型约束
            public class SomeFac<T> where T: myObj
            public class SomeFac<T> where T: myObj, new() //必须有一个构造函数
        
    7. 泛型委托
        预定义的三种泛型委托
            public delegate bool Predicate<in T>(T obj);//传入一个T类型的参数,返回bool类型的值
            
            public delegate void Action<in T1...T16>(T1 obj1, ..16)//传入0个到16个参数,无返回值
            public delegate TResult Func<in T1...T16, TResult>(T1 obj1, ..16)//传入0个到16个参数,返回一个T类型值
    
    ----------------------------------------------------------------
    
    8. 匿名方法:delegate (int item){方法体};
        var print = new Action<int>(delegate(int a){Console.WriteLine(a);});
        其中,匿名方法代码如下:
                delegate(int a){Console.WriteLine(a);}
    
    9. Lambda表达式:匿名方法的简化写法
        delegate(int a){Console.WriteLine(a);}
        更改为:
        a=>Console.WriteLine(a);//a的类型由编译器自动推断
    
        var print = new Action<int>(delegate(int a){Console.WriteLine(a);});
        简写为:
        var print = new Action<int>(a=>Console.WriteLine(a));
    
        =>是lambda操作符
        Console.WriteLine(a)是要执行的语句。
        如果是多条语句的话,可以用{}包起来。
        如果需要返回值的话,可以直接写return语句
    
    ----------------------------------------------------------------
    
    10. 扩展方法
        想给一个类型增加行为,通常是通过继承的方式实现。
        新的方式是使用扩展方法。
    
        public static void PrintString(this String val)
        {
            Console.WriteLinie(val);
        }
    
        之后,则可以这样调用。
        var a = "aaa;
        a.PrintString();
    
        本来string类型没有PrintString方法。
        但通过我们上面的代码,就给string类型"扩展"了一个PrintString方法
    
    
        
        (1)先决条件
         <1>扩展方法必须在一个非嵌套、非泛型的静态类中定义
         <2>扩展方法必须是一个静态方法
         <3>扩展方法至少要有一个参数【这个参数的类型就是增加行为的类型】
         <4>第一个参数必须附加this关键字作为前缀
         <5>第一个参数不能有其他修饰符(比如ref或者out)
         <6>第一个参数不能是指针类型
        (2)注意事项
         <1>跟前面提到的几个特性一样,扩展方法只会增加编译器的工作,不会影响性能(用继承的方式为一个类型增加特性反而会影响性能)
         <2>如果原来的类中有一个方法,跟你的扩展方法一样(至少用起来是一样),那么你的扩展方法奖不会被调用,编译器也不会提示你
         <3>扩展方法太强大了,会影响架构、模式、可读性等等等等....
        
    11. 迭代器
        每次针对集合类型编写foreach代码块,都是在使用迭代器
        这些集合类型都实现了IEnumerable接口,都有一个GetEnumerator方法。
            static IEnumerable<int> GetIterator()
            {
                Console.WriteLine("迭代器返回了1");
                yield return 1;
                Console.WriteLine("迭代器返回了2");
                yield return 2;
                Console.WriteLine("迭代器返回了3");
                yield return 3;
            }
        yield 关键字,在迭代器块中用于向枚举数对象提供值或发出迭代结束信号。
    
        注意事项
        <1>做foreach循环时多考虑线程安全性      
         在foreach时不要试图对被遍历的集合进行remove和add等操作
         任何集合,即使被标记为线程安全的,在foreach的时候,增加项和移除项的操作都会导致异常
         (我在这里犯过错)
        <2>IEnumerable接口是LINQ特性的核心接口
         只有实现了IEnumerable接口的集合
         才能执行相关的LINQ操作,比如select,where等
         这些操作,我们接下来会讲到。
    ----------------------------------------------------------------
    二、Linq
    【查询操作符、查询表达式】 1. 查询操作符   (1)源起 .net的设计者在类库中定义了一系列的扩展方法 来方便用户操作集合对象 这些扩展方法构成了LINQ的查询操作符   (2)使用 这一系列的扩展方法,比如: Where,Max,Select,Sum,Any,Average,All,Concat等 都是针对IEnumerable的对象进行扩展的 也就是说,只要实现了IEnumerable接口,就可以使用这些扩展方法 List<int> arr = new List<int>() { 1, 2, 3, 4, 5, 6, 7 }; var result = arr.Where(a => { return a > 3; }).Sum(); Where扩展方法,需要传入一个Func<int,bool>类型的泛型委托 这个泛型委托,需要一个int类型的输入参数和一个布尔类型的返回值 我们直接把a => { return a > 3; }这个lambda表达式传递给了Where方法 a就是int类型的输入参数,返回a是否大于3的结果 Sum扩展方法计算了Where扩展方法返回的集合的和。   (3)好处 arr.Where(a => { return a > 3; }).Sum(); 等同于 (from v in arr where v > 3 select v).Sum();   (4)标准查询操作符说明 <1>过滤   Where   用法:arr.Where(a => { return a > 3; })   说明:找到集合中满足指定条件的元素   OfType   用法:arr.OfType<int>()   说明:根据指定类型,筛选集合中的元素 <2>投影   Select   用法:arr.Select<int, string>(a => a.ToString());   说明:将集合中的每个元素投影的新集合中。上例中:新集合是一个IEnumerable<String>的集合   SelectMany   用法:arr.SelectMany<int, string>(a => { return new List<string>() { "a", a.ToString() }; });   说明:将序列的每个元素投影到一个序列中,最终把所有的序列合并 <3>还有很多查询操作符,请翻MSDN,以后有时间我将另起一篇文章把这些操作符写全。  2. 查询表达式 (1)源起   上面我们已经提到,使用查询操作符表示的扩展方法来操作集合   虽然已经很方便了,但在可读性和代码的语义来考虑,仍有不足   于是就产生了查询表达式的写法。   虽然这很像SQL语句,但他们却有着本质的不同。 (2)用法   from v in arr where v > 3 select v   这就是一个非常简单的查询表达式

      

  • 相关阅读:
    HTML语言基础
    过滤器Filter
    新闻实现分页显示
    [转]Jmeter使用入门
    [转]ZK工作原理
    [转]UT-IT-ST-BBIT-SDV-SIT-SVT
    Unix编码哲学
    火星坐标、百度坐标、WGS-84坐标相互转换及墨卡托投影坐标转经纬度JavaScript版
    递归公用表表达式概述
    java写word转pdf
  • 原文地址:https://www.cnblogs.com/liuweitoo/p/4305077.html
Copyright © 2020-2023  润新知