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
原文地址:https://www.cnblogs.com/haowuji/p/9504484.html