c# lambda表达式的5高频使用方法

Lambda表达式是一种匿名函数,可以用来创建委托或表达式树,它使用 => 运算符来指定输入参数和表达式或语句块。Lambda表达式可以简化匿名委托的使用,减少开发中需要编写的代码量。Lambda表达式可以分为表达式Lambda和语句Lambda,前者返回表达式的结果,后者可以包含多条语句。Lambda表达式还可以使用async和await关键字来创建包含异步处理的lambda表达式和语句。

在本文中,我们将介绍c# lambda表达式的5种典型的高频使用方法,分别是:

  • 使用lambda表达式作为委托或事件处理程序

  • 使用lambda表达式作为LINQ查询的谓词或选择器

  • 使用lambda表达式作为Task.Run或Task.Factory.StartNew的参数

  • 使用lambda表达式作为表达式树

  • 使用lambda表达式作为异步方法

在介绍这些使用方法之前,我们先回顾一下c#中委托的演变过程,以及lambda表达式的基本语法和特点。

c#中委托的演变过程

委托是一种引用类型,它可以封装一个具有特定参数和返回值类型的方法。委托可以用来实现回调函数、事件处理程序、匿名方法等功能。

在c# 1.0中,要创建一个委托实例,需要先定义一个委托类型,然后使用一个已经存在的方法来初始化委托。例如:

//定义一个委托类型delegateintCalculateHandler(int x, int y);

//定义一个符合委托类型签名的方法privateintSum(int x, int y)
{
    return x + y;
}

//创建一个委托实例,并用Sum方法初始化
CalculateHandler sumHandler = new CalculateHandler(Sum);

//调用委托实例
Console.WriteLine(sumHandler(1, 2)); //输出结果3

这种方式需要显式地定义一个委托类型和一个方法,比较繁琐。

在c# 2.0中,引入了匿名方法的概念,可以在创建委托实例时直接编写未命名的内联语句块,而不需要单独定义一个方法。例如:

//定义一个委托类型delegateintCalculateHandler(int x, int y);

//创建一个委托实例,并用匿名方法初始化
CalculateHandler sumHandler = delegate(int x, int y)
{
    return x + y;
};

//调用委托实例
Console.WriteLine(sumHandler(1, 2)); //输出结果3

这种方式省去了定义一个方法的步骤,但仍然需要定义一个委托类型,并且语法比较冗长。

在c# 3.0中,引入了lambda表达式,这是一种更简洁和更具表现力的匿名函数。lambda表达式可以直接表示为委托或表达式树的代码,并且可以自动推断输入参数的类型。例如:

//定义一个委托类型delegateintCalculateHandler(int x, int y);

//创建一个委托实例,并用lambda表达式初始化
CalculateHandler sumHandler = (x, y) =>
    return x + y;
};

//调用委托实例
Console.WriteLine(sumHandler(1, 2)); //输出结果3

这种方式不需要定义一个委托类型,也不需要使用delegate关键字,只需要使用 => 运算符来指定输入参数和表达式或语句块。lambda表达式的语法更加简洁和优雅。

lambda表达式的基本语法和特点

lambda表达式的基本语法如下:

(input-parameters) => expression-or-statement-block

其中,=> 运算符读作“goes to”,表示将输入参数映射到表达式或语句块。输入参数可以有0个、1个或多个,如果有多个参数,需要用逗号分隔,并用括号括起来。如果只有一个参数,可以省略括号。如果没有参数,必须使用空括号。例如:

() => Console.WriteLine("Hello"); //没有参数
x => x * x; //一个参数
(x, y) => x + y; //两个参数

表达式或语句块可以是一个单行的表达式,也可以是一个多行的语句块。如果是一个单行的表达式,lambda表达式会返回表达式的结果。如果是一个多行的语句块,需要用大括号括起来,并且可以使用return语句来返回值。例如:

x => x * x; //单行表达式,返回x的平方
(x, y) =>
{
    int result = x + y; //多行语句块return result; //使用return语句返回值
};

lambda表达式的特点有以下几点:

  • lambda表达式可以自动推断输入参数的类型,不需要显式地指定类型。例如:

//不需要指定x和y的类型
(x, y) => x + y;
  • lambda表达式可以根据上下文来确定其委托类型或表达式树类型。例如:

//根据委托类型推断lambda表达式的类型
Func<int, int, int> add = (x, y) => x + y;
Action<string> print = s => Console.WriteLine(s);

//根据事件处理程序推断lambda表达式的类型
button.Click += (sender, e) => Console.WriteLine("Button clicked");

//根据LINQ查询推断lambda表达式的类型var evenNumbers = numbers.Where(n => n % 2 == 0);
  • lambda表达式可以捕获外部变量,并在其主体中使用它们。这些变量被称为捕获变量,它们会在lambda表达式创建时被复制,并在lambda表达式执行时被更新。例如:

int factor = 2;
Func<int, int> multiplier = n => n * factor;
Console.WriteLine(multiplier(3)); //输出6
factor = 3;
Console.WriteLine(multiplier(3)); //输出9
  • lambda表达式可以使用async和await关键字来创建包含异步处理的lambda表达式和语句。这些lambda表达式被称为异步lambda,它们可以用来实现异步方法或任务。例如:

//使用async和await关键字创建异步lambda
Func<Task<int>> asyncLambda = async () =>
{
    await Task.Delay(1000);
    return42;
};

//调用异步lambda并获取结果int result = await asyncLambda();
Console.WriteLine(result); //输出42

使用lambda表达式作为委托或事件处理程序

委托是一种引用类型,它可以封装一个具有特定参数和返回值类型的方法。委托可以用来实现回调函数、事件处理程序、匿名方法等功能。lambda表达式可以直接表示为委托的代码,而不需要单独定义一个方法或一个委托类型。这样可以简化委托的创建和使用,提高代码的可读性和灵活性。

要使用lambda表达式作为委托,需要遵循以下几个步骤:

  • 定义一个委托类型,或者使用系统预定义的泛型委托类型,如Action<T>或Func<T>。

  • 创建一个lambda表达式,指定输入参数和表达式或语句块,并根据委托类型推断输入参数和返回值的类型。

  • 将lambda表达式赋值给一个委托变量,或者直接作为参数传递给其他方法。

  • 调用委托变量或方法,执行lambda表达式的主体。

例如,下面的代码演示了如何使用lambda表达式作为委托:

//定义一个委托类型delegateintCalculateHandler(int x, int y);

//创建一个lambda表达式,并赋值给一个委托变量
CalculateHandler sumHandler = (x, y) => x + y;

//调用委托变量,执行lambda表达式的主体
Console.WriteLine(sumHandler(1, 2)); //输出3//使用系统预定义的泛型委托类型
Func<int, int, int> multiplyHandler = (x, y) => x * y;

//调用委托变量,执行lambda表达式的主体
Console.WriteLine(multiplyHandler(2, 3)); //输出6//直接将lambda表达式作为参数传递给其他方法
List<int> numbers = new List<int>() { 1, 2, 3, 4, 5 };
numbers.ForEach(n => Console.WriteLine(n * n)); //输出1 4 9 16 25

事件是一种特殊的委托,它可以在某个对象发生特定行为时通知其他对象。事件处理程序是一种特殊的方法,它可以在事件被触发时执行一些操作。lambda表达式可以直接表示为事件处理程序的代码,而不需要单独定义一个方法。这样可以简化事件处理程序的创建和使用,提高代码的可读性和灵活性。

要使用lambda表达式作为事件处理程序,需要遵循以下几个步骤:

  • 定义一个事件,或者使用系统预定义的事件类型,如EventHandler<T>。

  • 创建一个lambda表达式,指定输入参数和表达式或语句块,并根据事件类型推断输入参数和返回值的类型。

  • 将lambda表达式添加到事件的订阅列表中,或者直接作为参数传递给其他方法。

  • 触发事件,执行所有订阅了该事件的lambda表达式的主体。

例如,下面的代码演示了如何使用lambda表达式作为事件处理程序:

//定义一个按钮类classButton
{
    //定义一个点击事件publicevent EventHandler Click;

    //定义一个触发点击事件的方法publicvoidOnClick()
    {
        //如果有订阅了该事件的处理程序,则调用它们
        Click?.Invoke(this, EventArgs.Empty);
    }
}

//创建一个按钮对象
Button button = new Button();

//创建一个lambda表达式,并添加到点击事件的订阅列表中
button.Click += (sender, e) =>
{
    Console.WriteLine("Button clicked");
};

//触发点击事件,执行lambda表达式的主体
button.OnClick(); //输出Button clicked

使用lambda表达式作为LINQ查询的谓词或选择器

LINQ是一种语言集成查询,它可以用来对各种数据源进行查询、筛选、排序、分组等操作。LINQ查询可以使用查询表达式或方法语法来编写,其中方法语法可以使用lambda表达式来指定查询的条件或投影。lambda表达式可以直接表示为谓词或选择器的代码,而不需要单独定义一个方法。这样可以简化LINQ查询的创建和使用,提高代码的可读性和灵活性。

要使用lambda表达式作为LINQ查询的谓词或选择器,需要遵循以下几个步骤:

  • 定义一个数据源,或者使用系统预定义的数据源类型,如IEnumerable<T>或IQueryable<T>。

  • 创建一个lambda表达式,指定输入参数和表达式或语句块,并根据数据源类型推断输入参数和返回值的类型。

  • 将lambda表达式作为参数传递给LINQ查询方法,如Where、Select、OrderBy等。

  • 遍历或转换LINQ查询结果,执行lambda表达式的主体。

例如,下面的代码演示了如何使用lambda表达式作为LINQ查询的谓词或选择器:

//定义一个数据源
List<int> numbers = new List<int>() { 1, 2, 3, 4, 5 };

//创建一个lambda表达式,并作为参数传递给Where方法,筛选出偶数var evenNumbers = numbers.Where(n => n % 2 == 0);

//遍历LINQ查询结果,执行lambda表达式的主体foreach (var n in evenNumbers)
{
    Console.WriteLine(n); //输出2 4
}

//创建一个lambda表达式,并作为参数传递给Select方法,将每个数乘以10var multipliedNumbers = numbers.Select(n => n * 10);

//遍历LINQ查询结果,执行lambda表达式的主体foreach (var n in multipliedNumbers)
{
    Console.WriteLine(n); //输出10 20 30 40 50
}

//创建一个lambda表达式,并作为参数传递给OrderBy方法,按照数值大小排序var sortedNumbers = numbers.OrderBy(n => n);

//遍历LINQ查询结果,执行lambda表达式的主体foreach (var n in sortedNumbers)
{
    Console.WriteLine(n); //输出1 2 3 4 5
}

使用lambda表达式作为Task.Run或Task.Factory.StartNew的参数

Task是一种表示异步操作的对象,它可以用来实现并行编程、异步编程、多线程编程等功能。Task可以使用Task.Run或Task.Factory.StartNew方法来创建和启动,这些方法可以接受一个委托作为参数,表示要在任务中执行的代码。lambda表达式可以直接表示为委托的代码,而不需要单独定义一个方法。这样可以简化Task的创建和使用,提高代码的可读性和灵活性。

要使用lambda表达式作为Task.Run或Task.Factory.StartNew的参数,需要遵循以下几个步骤:

  • 创建一个lambda表达式,指定输入参数和表达式或语句块,并根据委托类型推断输入参数和返回值的类型。

  • 将lambda表达式作为参数传递给Task.Run或Task.Factory.StartNew方法,创建并启动一个任务。

  • 等待任务完成,获取任务的结果或异常。

例如,下面的代码演示了如何使用lambda表达式作为Task.Run或Task.Factory.StartNew的参数:

//创建一个lambda表达式,并作为参数传递给Task.Run方法,创建并启动一个任务var task = Task.Run(() =>
{    //在任务中执行一些耗时的操作
    Thread.Sleep(1000);
    //返回一个结果
    return 42;
});

//等待任务完成,获取任务的结果
int result = task.Result;
Console.WriteLine(result); //输出42

//创建一个lambda表达式,并作为参数传递给Task.Factory.StartNew方法,创建并启动一个任务
var task2 = Task.Factory.StartNew(() =>
{
    //在任务中执行一些耗时的操作
    Thread.Sleep(1000);
    //抛出一个异常
    throw new Exception("Something went wrong");
});

//等待任务完成,获取任务的异常
try
{
    task2.Wait();
}
catch (AggregateException ae)
{
    foreach (var e in ae.InnerExceptions)
    {
        Console.WriteLine(e.Message); //输出Something went wrong
    }
}

使用lambda表达式作为表达式树

表达式树是一种表示代码结构的数据结构,它可以用来实现动态编译、元编程、LINQ提供程序等功能。表达式树可以使用Expression<TDelegate>类型来创建和表示,这是一种特殊的委托类型,它可以接受一个lambda表达式作为参数,表示要在表达式树中表示的代码。lambda表达式可以直接表示为表达式树的代码,而不需要单独定义一个方法。这样可以简化表达式树的创建和使用,提高代码的可读性和灵活性。

要使用lambda表达式作为表达式树,需要遵循以下几个步骤:

  • 创建一个lambda表达式,指定输入参数和表达式或语句块,并根据Expression<TDelegate>类型推断输入参数和返回值的类型。

  • 将lambda表达式作为参数传递给Expression<TDelegate>类型的构造函数,创建一个表达式树对象。

  • 遍历或转换表达式树对象,获取表达式树的结构或编译为委托。

例如,下面的代码演示了如何使用lambda表达式作为表达式树:

//创建一个lambda表达式,并作为参数传递给Expression<Func<int, int, int>>类型的构造函数,创建一个表达式树对象
Expression<Func<int, int, int>> expression = (x, y) => x + y;

//遍历表达式树对象,获取表达式树的结构
Console.WriteLine(expression); //输出(x, y) => (x + y)
Console.WriteLine(expression.Body); //输出(x + y)
Console.WriteLine(expression.Parameters[0]); //输出x
Console.WriteLine(expression.Parameters[1]); //输出y//转换表达式树对象,编译为委托
Func<int, int, int> func = expression.Compile();

//调用委托,执行lambda表达式的主体
Console.WriteLine(func(1, 2)); //输出3

使用lambda表达式作为异步方法

异步方法是一种使用async和await关键字来实现异步编程的方法,它可以用来实现非阻塞的UI、并发的网络请求、异步的IO操作等功能。异步方法可以使用Task或Task<T>类型来表示异步操作的结果,它们可以接受一个lambda表达式作为参数,表示要在异步方法中执行的代码。lambda表达式可以直接表示为异步方法的代码,而不需要单独定义一个方法。这样可以简化异步方法的创建和使用,提高代码的可读性和灵活性。

要使用lambda表达式作为异步方法,需要遵循以下几个步骤:

  • 创建一个lambda表达式,指定输入参数和表达式或语句块,并根据Task或Task<T>类型推断输入参数和返回值的类型。

  • 在lambda表达式中使用async和await

关键字来标记异步处理的代码,并使用await关键字来等待异步操作的完成。
- 将lambda表达式作为参数传递给Task或Task<T>类型的方法,如Task.Run或Task.FromResult,创建并启动一个异步方法。
- 等待异步方法完成,获取异步方法的结果或异常。

例如,下面的代码演示了如何使用lambda表达式作为异步方法:

```c#//创建一个lambda表达式,并作为参数传递给Task.Run方法,创建并启动一个异步方法var task = Task.Run(async () =>
{
    //在lambda表达式中使用async和await关键字来标记异步处理的代码await Task.Delay(1000); //等待1秒return42; //返回一个结果
});

//等待异步方法完成,获取异步方法的结果int result = await task;
Console.WriteLine(result); //输出42//创建一个lambda表达式,并作为参数传递给Task.FromResult方法,创建并启动一个异步方法var task2 = Task.FromResult(async () =>
{
    //在lambda表达式中使用async和await关键字来标记异步处理的代码await Task.Delay(1000); //等待1秒thrownew Exception("Something went wrong"); //抛出一个异常
});

//等待异步方法完成,获取异步方法的异常try
{
    await task2;
}
catch (Exception e)
{
    Console.WriteLine(e.Message); //输出Something went wrong
}

以上是c# lambda表达式的5高频使用方法

  • 0
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
C#中的Lambda表达式是一种简洁的语法形式,可以用来创建匿名函数。Lambda表达式通常用于函数式编程和LINQ查询。引用中提到,在日常使用C#编程的过程中,会经常使用lambda表达式Lambda表达式使用=>运算符,将输入参数映射到函数体中的表达式。表达式Lambda位于=>运算符右侧,称之为“表达式Lambda”。 Lambda表达式可以有一个或多个输入参数,并且可以返回一个值。在C#中,Lambda表达式的类型是委托类型,可以赋值给该委托类型的变量。 Lambda表达式的主体可以包含方法的调用,也可以只是一个表达式。当Lambda表达式只有一个表达式时,表示这里面只允许有一行代码。 例如,在C#中,可以使用Lambda表达式定义一个匿名方法,如下所示: ``` Func<int, int> func = x => x * 4; ``` 这个Lambda表达式接收一个int类型的参数x,并返回x乘以4的结果。可以通过调用func方法使用Lambda表达式,例如: ``` int result1 = func(5); ``` 这样就可以得到x等于5时的结果。Lambda表达式还可以在表达式主体中调用其他方法,如下所示: ``` func = x => x * Add(3, 2); int result2 = func(5); ``` 这个Lambda表达式将x乘以Add(3, 2)的结果作为返回值。在这个例子中,Add是一个方法,接收两个int类型的参数x和y,并返回它们的和。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [C# Lambda表达式](https://blog.csdn.net/qq_39847278/article/details/127525222)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

polsnet

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值