(C#基础)Linq学习理解

  一遍学习基础,一遍练习打字,很多乐趣。 

 代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;

namespace dazilianxi
{
    public  class Category
    {
        public int Id { get;set;}
        public string Name { get; set; }
    }
    public class Product {
        public int Id { get; set; }
        public string Name { get; set; }
        public Category Category { get; set; }
        public DateTime BuyDate { get; set; }
        public decimal Price { get; set; }

        public override string ToString()
        {
            return string.Format("编号:{0},名称:{1},类别:{2},购买时间:{3},价格{4}",Id,Name,Category.Name,BuyDate,Price);

        }
    }
    public static class ProductHelper
    {
        public static IEnumerable<Product> GetProducts()
        {
            Category cat1 = new Category();
            cat1.Id = 1;
            cat1.Name = "数码电子";
            Category cta2 = new Category();
            cta2.Id = 2;
            cta2.Name = "服饰类";

            List<Product> list = new List<Product>()
            {
                new Product(){ Id=1,Name="数码相机",Price=1899M,BuyDate=new DateTime(2015,11,13),Category=cat1
                },
                new Product(){Id=2,Name="录像机",Price=1000M,BuyDate=new DateTime(2015,1,8),Category=cat1},
                new Product(){Id=3,Name="体恤衫",Price=150M,BuyDate=new DateTime(2015,11,11),Category=cta2},
                new Product(){Id=4,Name="夹克衫",Price=180M,BuyDate=new DateTime(2015,8,9),Category=cta2}
            };
            return list;
        }
    }

    public class ProductComparer : IComparer<Product>, IEqualityComparer<Product>//居然要具体的类
    {
        public int Compare(Product x, Product y)
        {
            if (x == y)//如果类别名称相同就比较产品价格
            {
                return x.Price.CompareTo(y.Price);
            }
            else //如果类别名称不同,比较类别的编号
            {
                return x.Category.Id.CompareTo(y.Category.Id);
            }
        }

        public bool Equals(Product x, Product y)
        {
            if (x.Category.Name == y.Category.Name)
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        //这个是接口里的,一定要实现
        public int GetHashCode(Product obj)
        {
            return obj.GetHashCode();
        }    
    }

    public class PropertyComparer<T> : IEqualityComparer<T>
    {
        //需要比较的属性的PropertyInfo
        private PropertyInfo _PropertyInfo;

        //通过构造函数把需要比较的属性传进来
        public PropertyComparer(string propertyName)
        {
            _PropertyInfo = typeof(T).GetProperty(propertyName,BindingFlags.GetProperty | BindingFlags.Instance | BindingFlags.Public);//原来这个地方也可以有几个选项| 神了
            if (_PropertyInfo == null)
            {
                throw new ArgumentException(string.Format("{0} 不是{1}的属性", propertyName, typeof(T)));
            }
        }

        public bool Equals(T x, T y)
        {
            object xValue = _PropertyInfo.GetValue(x, null);
            object yValue = _PropertyInfo.GetValue(y, null);

            //如果xValue的属性值为null,那yValue的属性值也必须是null,才返回true
            if (xValue == null)
                return yValue == null;
            return xValue.Equals(yValue);
        }

        public int GetHashCode(T obj)
        {
            object propertyValue = _PropertyInfo.GetValue(obj, null);
            if (propertyValue == null)
                return 0;
            else
            {
                return propertyValue.GetHashCode();
            }
        }
    }
}
            var query = ProductHelper.GetProducts().OrderBy(x=>x.Id).OrderBy(b=>b.BuyDate).OrderByDescending(c=>c.Category.Id).ThenBy(p=>p.Price);
            showConsole(query);
            var query2 = ProductHelper.GetProducts().Select((x, index) => new { name=x.Name,index=index});//这里用到了一个匿名对象
            foreach(var item in query2){
                Console.WriteLine("名称:{0},索引{1}",item.name,item.index);
            }
            var query3 = ProductHelper.GetProducts().OrderBy(x => x, new ProductComparer());
            showConsole(query3);
            List<int> list = new List<int>()
            {
               3, 1,1,2,3,4,5,6,7,8,8,9
            };
            var query4 = list.Skip(7).Take(5);
            showConsole<int>(query4);
            Console.WriteLine("-------");
            var query5 = list.TakeWhile(x => x <= 5).TakeWhile(x => x > 1);//3
            showConsole(query5);
            Console.WriteLine("-------");
            var query6 = list.TakeWhile(x => x <= 5).Where(x => x > 1);//3,2,3,4,5
            showConsole(query6);
            Console.WriteLine("-------");
            var query7 = list.TakeWhile(x => x <= 5).Where(x => x > 1).Distinct();//3,2,4,5 去重
            showConsole(query7);
            Console.WriteLine("-------");
            int[] arr1 = { 0, 1, 2, 3 };
            int[] arr2 = { 2, 3, 4 };
            var query8 = arr1.Intersect(arr2);//取交集2,3
            showConsole<int>(query8);
            Console.WriteLine("-------");
            var query9 = arr1.Except(arr2);//Except()获取第一个集合中有,而第二个集合中没有的元素 0,1
            showConsole<int>(query9);
            Console.WriteLine("-------");
            var query10 = arr1.Concat(arr2); //Concat()将2个集合串联起来,不剔除重复元素  
            showConsole<int>(query10);
            Console.WriteLine("-------");
            var query11 = arr1.Union(arr2); //Union()将2个集合串联起来,剔除重复元素   
            showConsole<int>(query11);
            Console.WriteLine("-------");
            //Zip()合并2个集合中位置相同的元素,将2个元素的操作结果返回一个新的元素。如果两个集合的长度不相等,以长度短的为准。
            int[] arr11 = { 1, 2 };
            string[] arr22 = { "星期一", "星期二", "星期三" };
            var query12 = arr11.Zip(arr22, (x, y) => String.Format("{0},{1}", x, y));
            showConsole<string>(query12);

 private static void showConsole<T>(IEnumerable<T> list)
        {
            foreach (T item in list)
            {
                Console.WriteLine(item.ToString());
            }
        }

总结:

● 一般性的条件筛选:Where() 
● 返回具体的集合类型再进行链式操作:OfType() 
● 非泛型集合转换成泛型集合后再使用LINQ操作符:Cast() 
● 排序、链式排序:OrderBy(), ThenBy(),实现IComparer<T>接口可以自定义排序规则 
● 投影:Select() 
● 返回前N个,跳过N个,分页:Take()和Skip()   
● 返回符合/不符合条件,但不执行完遍历:TakeWhile()和SkipWhile() 
● 反转集合元素:Reverse() 
● 空集合处理:DefaultIfEmpty() 
● 剔除集合中的重复元素:Distinct(),实现IEqualityComparer<Category>可自定义相等规则,针对某具体类或写一个泛型方法 
● 分组以及分组后投影:GroupBy() 


● 2个集合的交集:Intersect() 
● 2个集合的查集:Except() 
● 2个集合的串联:Concat()和Union() 
● 2个集合的合并:Zip()

来源于:http://www.cnblogs.com/darrenji/p/3638561.html

          http://www.cnblogs.com/darrenji/p/3638788.html

          http://www.cnblogs.com/darrenji/p/3647823.html

非常基础的知识点,只有实践一次,才真的明白。

原文地址:https://www.cnblogs.com/annabook/p/4961666.html