C# lambda表达式

    • lambda表达式
    • 关于参数
    • 表达式或语句块
    • 一个神奇的例子与总结
      • 换句话说

lambda表达式

C# 中的 lambda 表达式是一种简洁的表示匿名函数的方法。Lambda 表达式特别用于 LINQ 查询、事件处理程序、回调函数等场景中,它使得代码更加简洁和易于阅读。

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

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

这里 input-parameterslambda 表达式的参数列表,它可以包含零个、一个或多个参数。=>lambda 运算符,它分隔参数列表和表达式或语句块。expression-or-statement-blocklambda 主体,可以是单个表达式或语句块。

下面是一些 lambda 表达式的例子:

无参数 lambda 表达式:

() => Console.WriteLine("Hello, World!")

单个参数 lambda 表达式:

x => x * x // 这是一个简单的平方计算 lambda

多个参数 lambda 表达式:

(x, y) => x + y // 这是一个简单的加法计算 lambda

带有语句块的 lambda 表达式:

(x, y) => {  int sum = x + y;  return sum * sum; // 返回两数之和的平方  
}

在实际使用中,lambda 表达式经常与委托或 FuncAction泛型委托结合使用。例如:

Func<int, int, int> add = (x, y) => x + y;  
int result = add(5, 3); // result 将会是 8

在这个例子中,我们定义了一个名为 addFunc<int, int, int> 类型的委托,它接受两个 int 类型的参数并返回一个 int 类型的值。Lambda 表达式 (x, y) => x + y 被赋值给这个委托,然后我们可以像调用普通方法一样调用这个委托。

Lambda 表达式在 LINQ 查询中也非常有用,例如:

List<int> numbers = new List<int> { 1, 2, 3, 4, 5 };  
var evenNumbers = numbers.Where(n => n % 2 == 0).ToList();
// 筛选偶数

在这个 LINQ 查询中,n => n % 2 == 0 是一个 lambda 表达式,它定义了筛选偶数的条件。

关于参数

C#中,当使用lambda表达式时,参数的类型确实可以省略,这是因为在大多数情况下,编译器可以根据lambda表达式使用的上下文(比如它赋值给的委托类型或者它所在的方法签名)来推断出参数的类型。这称为类型推断

例如,如果你有一个接受Func<int, int, bool>委托的方法,你可以这样传递一个lambda表达式,而不需要显式指定参数类型:

Func<int, int, bool> isDivisible = (a, b) => a % b == 0;

在这个例子中,编译器可以推断出ab都是int类型,因为Func<int, int, bool>委托期望两个int类型的参数和一个bool类型的返回值。

然而,在某些情况下,你可能需要显式指定参数类型,特别是当lambda表达式没有直接赋值给委托或者当上下文不足以让编译器进行类型推断时。在这些情况下,你可以像下面这样显式指定参数类型:

(int a, int b) => a % b == 0

显式指定类型可以提供更好的代码可读性,特别是在复杂的lambda表达式或者当参数类型不是显而易见的时候。不过,在大多数简单场景中,省略类型并使用类型推断可以使代码更简洁。

总的来说,是否需要在lambda表达式中指定参数类型取决于具体的使用场景和上下文。在能够利用类型推断的情况下,通常可以省略类型以简化代码。

表达式或语句块

C#中,lambda表达式的返回行为取决于它的使用上下文。如果lambda表达式被赋值给一个返回类型的委托(比如Func系列委托),或者它用于表达式树中且需要返回一个值,那么lambda表达式必须包含返回语句(return),除非它的主体本身就是一个表达式(在这种情况下,表达式的值就是lambda的返回值)。

如果lambda表达式赋值给的是一个没有返回值的委托(比如Action系列委托),或者它是事件处理器等不需要返回值的场景,那么它不应该包含return语句。在这些情况下,lambda表达式的主体通常是一个语句块,执行一系列操作但不返回任何值。

以下是一些例子来说明这些概念:

有返回值的lambda表达式(使用return):

Func<int, int, bool> isDivisible = (a, b) => {  return a % b == 0; // 使用return语句返回bool值  
};

或者,如果lambda的主体只是一个表达式,你可以省略大括号和return语句:

Func<int, int, bool> isDivisible = (a, b) => a % b == 0; 
// 表达式的结果就是返回值

没有返回值的lambda表达式(不使用return):

Action<string> printMessage = message => {  Console.WriteLine(message); // 执行操作,不返回任何值  
};

在这个例子中,printMessage是一个Action<string>类型的委托,它接受一个字符串参数并执行一个操作(打印消息到控制台),但不返回任何值。因此,lambda表达式的主体是一个语句块,它包含了一系列操作语句,而不是一个返回语句。

总结来说,是否需要在lambda表达式中使用return语句取决于该lambda表达式所代表的函数的预期行为:是否需要返回一个值。如果需要返回值,则必须使用return语句(除非lambda的主体本身就是一个表达式);如果不需要返回值,则不应该使用return语句。

一个神奇的例子与总结

class TODO {public static void Main(String[] args) {Func<int, int ,double >rule = (x, y) => {return x + y;};Console.WriteLine(rule(1, 2));}
}/*
var rule = new Func<int, int, double>((x, y) => {return x + y;
});
*/

C#中,你提供的两个代码片段定义了一个接受两个int类型参数并返回一个double类型结果的Func委托。虽然这两个代码片段在功能上完全相同,但它们在语法和可读性方面有一些细微的差别。

第一个代码片段

Func<int, int, double> rule = (x, y) => {  return x + y;  
};

在这个片段中,rule是一个Func<int, int, double>类型的变量,它直接通过lambda表达式进行初始化。这种语法在C#中非常常见,因为它简洁且直接。这里,lambda表达式(x, y) => { return x + y; }定义了委托的行为。

第二个代码片段

var rule = new Func<int, int, double>((x, y) => {  return x + y;  
});

注意其中的varFunc<int, int, double>

在这个片段中,rule同样是一个Func<int, int, double>类型的变量,但它是通过new关键字和Func的构造函数来初始化的。虽然这种语法是完全有效的,但它通常不如第一个片段那样常见或推荐,因为它稍微冗长一些。不过,这种语法在某些情况下可能更清晰,尤其是当需要在初始化委托的同时进行其他操作时。

区别总结
语法简洁性:第一个代码片段更简洁,因为它直接通过lambda表达式进行初始化,而不需要使用new关键字和构造函数。

可读性:对于大多数C#开发者来说,第一个代码片段可能更易于阅读和理解,因为它直接反映了委托的类型和它的行为。

性能:在实际运行时,这两种语法在性能上是没有区别的。它们都会创建一个新的委托实例,并将lambda表达式编译成的方法作为该委托的调用目标。

灵活性:虽然第一个代码片段更常见,但第二个代码片段在某些特定场景下可能更有用,尤其是当需要更复杂的初始化逻辑时。

在实际编程中,建议使用第一个代码片段的语法,因为它更简洁、更常见,也更容易被其他开发者理解。

换句话说

C#中,当你使用lambda表达式来创建委托的实例时,你实际上是在隐式地创建一个匿名函数并将其赋值给委托变量。在这个过程中,你不需要显式地使用new关键字来创建委托的实例,因为编译器会自动为你处理这些细节。

例如,下面的代码展示了如何使用lambda表达式来隐式地创建一个Func<int, int, bool>类型的委托实例:

Func<int, int, bool> isDivisible = (x, y) => x % y == 0;

在这个例子中,我们没有使用new关键字来创建Func<int, int, bool>的实例。相反,我们直接将lambda表达式(x, y) => x % y == 0赋值给了isDivisible变量。编译器会自动处理lambda表达式的编译和委托实例的创建。

然而,如果你想要显式地通过委托的构造函数来创建一个委托实例,那么你需要使用new关键字,就像这样:

Func<int, int, bool> isDivisible = new Func<int, int, bool>((x, y) => x % y == 0);

虽然这种语法是有效的,但它通常是不必要的,并且会使代码看起来更加冗长。直接使用lambda表达式来赋值给委托变量是更常见和推荐的做法。

总之,当你使用lambda表达式来创建委托实例时,你不需要显式地使用new关键字。编译器会自动为你处理这些细节,使代码更加简洁和易读。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/795215.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

图像处理与视觉感知---期末复习重点(6)

文章目录 一、图像分割二、间断检测2.1 概述2.2 点检测2.3 线检测2.4 边缘检测 三、边缘连接3.1 概述3.2 Hough变换3.3 例子3.4 Hough变换的具体步骤3.5 Hough变换的法线表示形式3.6 Hough变换的扩展 四、阈值处理4.1 概述4.2 计算基本全局阈值算法4.3 自适应阈值 五、基于区域…

SV学习笔记(四)

OCP Open Closed Principle 开闭原则 文章目录 随机约束和分布为什么需要随机&#xff1f;为什么需要约束&#xff1f;我们需要随机什么&#xff1f;声明随机变量的类什么是约束权重分布集合成员和inside条件约束双向约束 约束块控制打开或关闭约束内嵌约束 随机函数pre_random…

LeetCode-131. 分割回文串【字符串 动态规划 回溯】

LeetCode-131. 分割回文串【字符串 动态规划 回溯】 题目描述&#xff1a;解题思路一&#xff1a;回溯&#xff0c; 回溯三部曲解题思路二&#xff1a;0解题思路三&#xff1a;0 题目描述&#xff1a; 给你一个字符串 s&#xff0c;请你将 s 分割成一些子串&#xff0c;使每个…

微信小程序中选中手机相册图片上传到服务器的方法

思路&#xff1a; 实现图片上传我们需要使用chooseImg和uploadFile这两个api。 1. 微信小程序中的chooseImg是一个API&#xff0c;用于在用户相册或相机中选择图片上传。它可以让用户在小程序中选择上传图片&#xff0c;以便进行下一步操作&#xff0c;例如将其发送给朋友或将其…

vue项目安装下载项目包,报错Clear up some disk space and try again

npm install 报错&#xff1a; Clear up some disk space and try again 解决办法&#xff1a; npm cache clean --force npm cache clear --force && npm install --no-shrinkwrap --update-binary

常用软件架构模式优缺点及应用场景

1、分层架构模式 最常见的架构模式就是分层架构或者称为 n 层架构。大部分软件架构师、设计师和开发者都对这个架构模式非常熟悉。尽管对于层的数量和类型没有具体限制&#xff0c;但大部分分层架构主要由四层组成&#xff1a;展现层、业务层、持久层和数据库层&#xff0c;如…

Peter算法小课堂—树状数组

大家好&#xff0c;我是人见人爱&#xff0c;花见花开&#xff0c;车见车爆胎的树状数组Peter Pan&#xff0c;hhh 讲正文前&#xff0c;先来一个长文警告⚠很重要的知识点&#xff1a;L SB&#xff08;SB&#xff1f;&#xff09; LSB 怎么算呢&#xff1f; 哦……懂了&…

LeetCode-79. 单词搜索【数组 字符串 回溯 矩阵】

LeetCode-79. 单词搜索【数组 字符串 回溯 矩阵】 题目描述&#xff1a;解题思路一&#xff1a;回溯 回溯三部曲。这里比较关键的是给board做标记&#xff0c;防止之后搜索时重复访问。解题思路二&#xff1a;回溯算法 dfs,直接看代码,很容易理解。visited哈希&#xff0c;防止…

这个世界万物存在只有一种关系:博弈

$上证指数(SH000001)$ 我能给各位最大的帮助可能就是第一个从红警游戏引入了情绪周期视角的概念&#xff0c;而这个概念可以帮助很多人理解市场成为一种可能性&#xff0c;如果不理解可以重新回归游戏进行反复体验&#xff0c;你体验的足够多&#xff0c;思考的足够多&#xff…

力扣日记4.6-【动态规划篇】746. 使用最小花费爬楼梯

力扣日记&#xff1a;【动态规划篇】746. 使用最小花费爬楼梯 日期&#xff1a;2024.4.6 参考&#xff1a;代码随想录、力扣 746. 使用最小花费爬楼梯 题目描述 难度&#xff1a;简单 给你一个整数数组 cost &#xff0c;其中 cost[i] 是从楼梯第 i 个台阶向上爬需要支付的费用…

计算机网络——33多点访问协议

多点访问协议 多路访问链路和协议 两种类型的链路&#xff08;一个子网内部链路连接形式&#xff09; 点对点 拨号访问的PPP以太网交换机和主机之间的点对点链路 广播 传统以太网HFC上行链路802.11无线局域网 多路访问协议 单个共享的广播型链路 2个过更多结点同时传送&am…

c# 指数搜索(Exponential Search)

该搜索算法的名称可能会产生误导&#xff0c;因为它的工作时间为 O(Log n)。该名称来自于它搜索元素的方式。 给定一个已排序的数组和要 搜索的元素 x&#xff0c;找到 x 在数组中的位置。 输入&#xff1a;arr[] {10, 20, 40, 45, 55} x 45 输出&#xff1a;在索…

Aurora8b10b(1)IP核介绍并基于IP核进行设计

文章目录 前言一、IP核设置二、基于IP核进行设计2.1、设计框图2.2、aurora_8b10b_0模块2.3、aurora_8b10b_0_CLOCK_MODULE2.4、aurora_8b10b_0_SUPPORT_RESET_LOGIC2.5、aurora8b10b_channel模块2.6、IBUFDS_GTE2模块2.7、aurora_8b10b_0_gt_common_wrapper模块2.8、aurora8b10…

Element UI 消息提示 Message

1. Message 消息提示 本文使用的是 Element UI v2.5.13 Message 常用于主动操作后的反馈提示。比如&#xff1a;用于提交表单后的提示&#xff0c;成功或失败 全局方法 Element 为 Vue.prototype 添加了全局方法 $message&#xff0c;因此可以通过 Vue 实例直接调用 export …

GIS水文分析填充伪洼地学习

1 基本操作 洼地是指流域内被较高高程所包围的局部区域&#xff1b; 分为自然洼地和伪洼地&#xff1b; 自然洼地是自然界实际存在的洼地&#xff1b; 在 DEM 数据中&#xff0c;由于数据处理的误差和不合适的插值方法所产生的洼地&#xff0c;称为伪洼地&#xff1b; DEM 数据…

文件服务器之二:SAMBA服务器

文章目录 什么是SAMBASAMBA的发展历史与名称的由来SAMBA常见的应用 SAMBA服务器基础配置配置共享资源Windows挂载共享Linux挂载共享 什么是SAMBA 下图来自百度百科 SAMBA的发展历史与名称的由来 Samba是一款开源的文件共享软件&#xff0c;它基于SMB&#xff08;Server Messa…

Python-链表常用操作方法

在 Python 中&#xff0c;可以使用类来表示链表节点&#xff0c;然后通过链接节点来构建链表。以下是一些 Python 中链表的常用方法和操作&#xff1a; 定义链表节点类&#xff1a; class ListNode:def __init__(self, val0, nextNone):self.val valself.next next创建链表&a…

秒杀设计思路

目录 1. 系统前端优化 2. 应用层优化 3. 负载均衡 4. 业务层优化 5. 数据库优化 6. 缓存策略 7. 后端优化 8. 安全防护 9. 系统监控和预警 秒杀系统设计需要考虑高并发、高可用、低延迟等因素&#xff0c;以下是一些常见的设计方案&#xff1a; 1. 系统前端优化 静态…

TensorFlow Lite 在安卓开发中的应用及其关键组件研究

摘要 随着移动设备计算能力的增强和人工智能技术的发展&#xff0c;Google 推出的 TensorFlow Lite 成为了在安卓平台上实现本地机器学习模型部署的重要工具。本文旨在全面探讨 TensorFlow Lite 在安卓开发中的角色、优势与局限性&#xff0c;分析其典型应用场景&#xff0c;并…

Python环境搭建—安装PyCharm开发工具

&#x1f947;作者简介&#xff1a;CSDN内容合伙人、新星计划第三季Python赛道Top1 &#x1f525;本文已收录于Python系列专栏&#xff1a; 零基础学Python &#x1f4ac;订阅专栏后可私信博主进入Python学习交流群&#xff0c;进群可领取Python视频教程以及Python相关电子书合…