zoukankan      html  css  js  c++  java
  • C# 匿名方法、Linq

    C# 匿名方法、Linq


    1 匿名方法 lambda表达式

    在我们之前学习委托的时候有一个求大于20岁的学生信息的功能,现在我们使用匿名方法优化下它:

    学生类:

        public class Student
        {
            public string Name { get; set; }
    
            public int Age { get; set; }
            public string Email { get; set; }
    
            public Student(string name, int age, string email)
            {
                this.Name = name;
                this.Age = age;
                this.Email = email;
            }
    
            public Student() { }
        }
    

    初始化信息:

    List<Student> students = new List<Student>();
    students.Add(new Student("Oliver", 18, "123@qq.com"));
    students.Add(new Student("小白", 19, "123@sina.com"));
    students.Add(new Student("老K", 28, "123@163.com"));
    students.Add(new Student("土豆", 16, "232@sina.com"));
    students.Add(new Student("番茄", 33, "fanqie@qq.com"));
    students.Add(new Student("小红", 22, "24424@163.com"));
    students.Add(new Student("黎明", 18, "2232@126.com"));
    students.Add(new Student("黄昏", 21, "huanghun@qq.com"));
    

    匿名方法

    使用委托的方式

    var newList = students.MyWhere(this.GetAgeThan);//筛选年龄大于20的学生
    Console.WriteLine(newList.Count());
    

    GetAgeThan方法

    bool GetAgeThan(Student s)
    {
        return s.Age > 20;
    }
    

    匿名方法1,将方法体直接写到参数中,传递给委托

    var age = 20;
    var newList = students.MyWhere(delegate (Student s)
    {
        return s.Age > age;//匿名方法可以访问方法外的变量
    });//筛选年龄大于20的学生
    Console.WriteLine(newList.Count());
    

    匿名方法2:省略委托,使用=> 区别参数与方法体

    var newList = students.MyWhere((Student s) =>
    {
        return s.Age > 20;
    });//筛选年龄大于20的学生
    Console.WriteLine(newList.Count());
    

    匿名方法3:省略参数类型

    var newList = students.MyWhere((s) => { return s.Age > 20; });//筛选年龄大于20的学生
    Console.WriteLine(newList.Count());
    

    匿名方法4:省略参数的括号

    var newList = students.MyWhere(s => { return s.Age > 20; });//筛选年龄大于20的学生
    Console.WriteLine(newList.Count());
    

    匿名方法5:当方法体中只有一行时,可以省略方法体的括号与return关键字(是不是我们的Lambda表达式很像呢)

    var newList = students.MyWhere(s => s.Age > 20);//筛选年龄大于20的学生
    Console.WriteLine(newList.Count());
    

    MyWhere方法

    /// <summary>
    /// 使用静态类加静态方法,直接调用
    /// </summary>
    public static class ExtendMethod
    {
    
        /// <summary>
        /// 1 基于委托封装解耦,去掉重复代码,完成通用代码
        /// 根据逻辑条件筛选数据
        /// </summary>
        /// <param name="list">列表</param>
        /// <param name="where">逻辑条件</param>
        /// <returns>筛选结果</returns>
        public static List<Student> MyWhere1(this List<Student> list, Func<Student, bool> where)
        {
            List<Student> newList = new List<Student>();
            foreach (var item in list)
            {
                if (where(item))
                {
                    newList.Add(item);
                }
            }
            return newList;
        }
    
        /// <summary>
        /// 2 泛型,应对各种数据类型 
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="list"></param>
        /// <param name="where"></param>
        /// <returns></returns>
        public static List<T> MyWhere2<T>(this List<T> list, Func<T, bool> where)
        {
            List<T> newList = new List<T>();
            foreach (var item in list)
            {
                if (where(item))
                {
                    newList.Add(item);
                }
            }
            return newList;
        }
    
    
        /// <summary>
        /// 3 加迭代器,按需获取
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="list"></param>
        /// <param name="where"></param>
        /// <returns></returns>
        public static IEnumerable<T> MyWhere<T>(this IEnumerable<T> list, Func<T, bool> where)
        {
            foreach (var item in list)
            {
                if (where(item))
                {
                    yield return item;
                }
            }
        }
    }
    

    2 匿名类 var

    使用匿名类var,编译器可以根据返回的信息自动退税相应的类型。

    //匿名类
    var newList = students.Select(c => new
    {
        c.Age,
        c.Name,
        NameLength = c.Name.Length
    });
    foreach (var item in newList)
    {
        Console.WriteLine($"Name:{item.Name}	Age:{item.Age}	NameLength:{item.NameLength} ");
    }
    

    3 linq常用方法介绍

    Where

    int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };
    var newNumbers = numbers.Where(c => c > 6);
    Console.WriteLine("Where:" + string.Join(",", newNumbers));
    //输出结果:Where:9,8,7
    

    Select

    //Select  得到学生的姓名列表
    var nameList1 = students.Select(c => c.Name);
    Console.WriteLine("Select:" + string.Join(",", nameList1));
    //输出:Select:Oliver,小白,老K,土豆,番茄,小红,黎明,黄昏
    

    Take

    //Take  从序列的开头返回指定的数量的连续元素。
    int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };
    var newNumbers = numbers.Take(2);
    Console.WriteLine("Take:" + string.Join(",", newNumbers));
    //输出结果:Take:5,4
    

    TakeWhile

    //TakeWhile 返回序列中的元素,只要指定的条件为真。
    //返回结果:System.Collections.Generic.IEnumerable`1 ,其中包含输入序列中出现测试不再能够通过在元素之前的元素。
    int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };
    
    //在这里需要注意.使用TakeWhile获取小于6的元素,是从第一个元素开始,
    //一直到不满足其小于6这个条件为止.也就是执行到和9这个元素比较后,就结束比较了
    //可以想象一下执行过程.
    //5<6=true;4<6=true;1<6=true;3<6=true
    //9<6=false;   这里就停止继续比较了 
    var newNumbers = numbers.TakeWhile(n => n < 6);
    Console.WriteLine("TakeWhile:" + string.Join(",", newNumbers));
    //输出结果:TakeWhile:5,4,1,3
    

    Skip

    //Skip 跳过指定的数量的序列中的元素,然后返回剩余元素。
    int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };
    var newNumbers = numbers.Skip(5);
    Console.WriteLine("Skip:" + string.Join(",", newNumbers));
    //输出结果:Skip:8,6,7,2,0
    

    SKipWhere

    //SKipWhere  只要指定的条件为 true,然后返回剩余元素,跳过序列中的元素。
    int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };
    var newNumbers = numbers.SkipWhile(c => c < 6);
    Console.WriteLine("SKipWhere:" + string.Join(",", newNumbers));
    //输出结果:SKipWhere:9,8,6,7,2,0
    

    OrderBy

    //OrderBy  正序。
    int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };
    var newNumbers = numbers.OrderBy(c => c);
    Console.WriteLine("OrderBy:" + string.Join(",", newNumbers));
    //输出结果:OrderBy:0,1,2,3,4,5,6,7,8,9
    

    OrderByDescending

    //OrderByDescending  倒序。
    int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };
    var newNumbers = numbers.OrderByDescending(c => c);
    Console.WriteLine("OrderByDescending:" + string.Join(",", newNumbers));
    //输出结果:OrderByDescending:9,8,7,6,5,4,3,2,1,0
    

    ThenBy

    //ThenBy 执行后续排序以根据某个键按升序对序列的元素。
    //如同sql的: select * from student order by age,name;
    

    ThenByDescending

    //ThenByDescending  根据某个键将执行后续排序顺序,按降序对序列的元素。
    //如同sql的: select * from student order by age,name desc;
    

    GroupBy

    int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0, 2, 3, 3, 4 };
    var newNumbers = numbers.GroupBy(c => c).Select(group =>
    string.Format("{0}:{1}", group.Key, group.Count())
    );
    Console.WriteLine("GroupBy:" + string.Join(",", newNumbers));
    //输出结果:GroupBy:5:1,4:2,1:1,3:3,9:1,8:1,6:1,7:1,2:2,0:1
    

    Distinct

    //Distinct   通过使用的默认相等比较器对值进行比较从序列返回非重复元素。
    int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0, 2, 3, 3, 4 };
    var newNumbers = numbers.Distinct();
    Console.WriteLine("Distinct:" + string.Join(",", newNumbers));
    //输出结果:Distinct:5,4,1,3,9,8,6,7,2,0
    

    Min

    //Min   返回序列中的最小值 System.Int32 值。
    int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0, 2, 3, 3, 4 };
    var minValue = numbers.Min();
    Console.WriteLine("Min:" + minValue);
    //输出结果:Min:0
    

    Max

    //Min  返回序列中的最大值 System.Int32 值。
    int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0, 2, 3, 3, 4 };
    var maxValue = numbers.Max();
    Console.WriteLine("Max:" + maxValue);
    //输出结果:Max:9
    

    Average

    //Average  计算序列的平均值 System.Int32 值。
    int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0, 2, 3, 3, 4 };
    var avg = numbers.Average();
    Console.WriteLine("Avg:" + avg);
    //输出结果:Avg:4.07142857142857
    

    Sum

    //Sum  计算的一系列总和 System.Int32 值。
    int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0, 2, 3, 3, 4 };
    var sum = numbers.Sum();
    Console.WriteLine("Sum:" + sum);
    //输出结果:Sum:57
    

    First

    //First  计算的一系列总和 System.Int32 值。
    int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0, 2, 3, 3, 4 };
    var number = numbers.First();
    Console.WriteLine("First:" + number);
    //输出结果:First:5
    

    FirstOrDefault

    //FirstOrDefault  返回序列中的第一个元素;如果序列中不包含任何元素,则返回默认值。
    int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0, 2, 3, 3, 4 };
    var number = numbers.Where(c => c == 18).FirstOrDefault();
    Console.WriteLine("FirstOrDefault:" + number);
    //输出结果:FirstOrDefault:0
    
  • 相关阅读:
    标签的讲解
    属性分类
    LeetCode 003. 无重复字符的最长子串 双指针
    Leetcode 136. 只出现一次的数字 异或性质
    Leetcode 231. 2的幂 数学
    LeetCode 21. 合并两个有序链表
    象棋博弈资源
    acwing 343. 排序 topsort floyd 传播闭包
    Leetcode 945 使数组唯一的最小增量 贪心
    Leetcode 785 判断二分图 BFS 二分染色
  • 原文地址:https://www.cnblogs.com/haowuji/p/9504484.html
Copyright © 2011-2022 走看看