基础知识---委托和 lambda
委托定义类型,类型指定特定方法签名。 可将满足此签名的方法(静态或实例)分配给该类型的变量,然后(使用适当参数)直接调用该方法,或将其作为参数本身传递给另一方法再进行调用。 以下示例演示了委托的用法。
using System;
using System.Linq; public class Program
{
public delegate string Reverse(string s); static string ReverseString(string s)
{
return new string(s.Reverse().ToArray());
} static void Main(string[] args)
{
Reverse rev = ReverseString; Console.WriteLine(rev("a string"));
}
}
public delegate string Reverse(string s);行创建特定签名的委托类型,在本例中即接受字符串参数并返回字符串参数的方法。static string ReverseString(string s)方法与定义的委托类型具有完全相同的签名,用于实现委托。Reverse rev = ReverseString;行显示可将方法分配给相应委托类型的变量。Console.WriteLine(rev("a string"));行演示如何使用委托类型的变量来调用委托。
为简化开发过程,.NET 包含一组委托类型,程序员可重用这些类型而无需创建新类型。 其中包括 Func<>、Action<> 和 Predicate<>,可用于 .NET API 的各个位置,无需定义新委托类型。 当然,从这三者的签名可以看出它们之间存在某些差异,主要影响其既定用途:
Action<>用于需要使用委托参数执行操作的情况。Func<>通常用于现有转换的情况,也就是说需要将委托参数转换为其他结果时。 最好的示例就是投影。Predicate<>用于需要确定参数是否满足委托条件的情况。 也可将其写作Func<T, bool>。
现在可使用 Func<> 委托而非自定义类型重新编写上述示例。 程序将照旧继续运行。
using System;
using System.Linq; public class Program
{
static string ReverseString(string s)
{
return new string(s.Reverse().ToArray());
} static void Main(string[] args)
{
Func<string, string> rev = ReverseString; Console.WriteLine(rev("a string"));
}
}
对于此简单示例而言,在 Main 方法之外定义方法似乎有些多余。 因此 .NET Framework 2.0 引入了匿名委托的概念。 在其支持下,可创建“内联”委托,而无需指定任何其他类型或方法。 只需在所需位置内联委托的定义即可。
例如,要进行切换并使用匿名委托筛选出只有偶数的列表,然后将其打印到控制台。
using System;
using System.Collections.Generic; public class Program
{
public static void Main(string[] args)
{
List<int> list = new List<int>(); for (int i = ; i <= ; i++)
{
list.Add(i);
} List<int> result = list.FindAll(
delegate (int no)
{
return (no % == );
}
); foreach (var item in result)
{
Console.WriteLine(item);
}
}
}
如你所见,该委托的正文只是一组表达式,其他所有委托也是如此。 但它并非单独定义,而是在调用List<T>.FindAll 方法时临时引入。
但是,即使使用此方法,仍有许多可以丢弃的代码。 此时就需要使用 lambda 表达式。
lambda 表达式(或简称“lambda”)在 C# 3.0 中作为语言集成查询的 (LINQ) 核心构建基块被首次引入。 这种表达式只是使用委托的更方便的语法。 它们将声明签名和方法正文,但在分配到委托之前没有自己的正式标识。 与委托不同,可将其作为事件注册的左侧内容或在各种 LINQ 子句和方法中直接分配。
由于 lambda 表达式只是指定委托的另一种方式,因此应可重新编写上述示例,令其使用 lambda 表达式而不是匿名委托。
using System;
using System.Collections.Generic; public class Program
{
public static void Main(string[] args)
{
List<int> list = new List<int>(); for (int i = ; i <= ; i++)
{
list.Add(i);
} List<int> result = list.FindAll(i => i % == ); foreach (var item in result)
{
Console.WriteLine(item);
}
}
}
在前面的示例中,所使用的 Lambda 表达式为 i => i % 2 == 0。 再次强调,它只是使用委托的一种非常方便的语法,因此其实际行为与使用匿名委托时相同。
再次强调,lambda 只是委托,这意味着可将其顺利用作事件处理程序,如以下代码片段所示。
public MainWindow()
{
InitializeComponent(); Loaded += (o, e) =>
{
this.Title = "Loaded";
};
}
此上下文中的 += 运算符用于订阅事件。
基础知识---委托和 lambda的更多相关文章
- C# 基础知识系列- 6 Lambda表达式和Linq简单介绍
前言 C#的lambda和Linq可以说是一大亮点,C#的Lambda无处不在,Linq在数据查询上也有着举足轻重的地位. 那么什么是Linq呢,Linq是 Language Intergrated ...
- 《Java基础知识》Java Lambda表达式
接触Lambda表达式的时候,第一感觉就是,这个是啥?我居然看不懂,于是开始寻找资料,必须弄懂它. 先来看一个案例: @FunctionalInterface public interface MyL ...
- C#基础知识之事件和委托
本文中,我将通过两个范例由浅入深地讲述什么是委托.为什么要使用委托.委托的调用方式.事件的由来..Net Framework中的委托和事件.委托和事件对Observer设计模式的意义,对它们的中间代码 ...
- C#基础知识---Lambda表达式
一.Lambda表达式简介 Lambda表达式可以理解为匿名函数,可以包含表达式和语句.它提供了一种便利的形式来创建委托. Lambda表达式使用这个运算符--- "=>", ...
- [C# 基础知识系列]专题一:深入解析委托——C#中为什么要引入委托
转自http://www.cnblogs.com/zhili/archive/2012/10/22/Delegate.html 引言: 对于一些刚接触C# 不久的朋友可能会对C#中一些基本特性理解的不 ...
- C#基础加强篇—委托、Lambda表达式和事件(下)
3.事件 事件作为C#中的一种类型,为类和类的实例定义发出通知的能力,从而将事件和可执行代码捆绑在了一起.事件是对象发送的消息,以发信号通知操作的发生.操作可能是由用户交互引起的,也可能是由某些其他的 ...
- JAVA基础知识|lambda与stream
lambda与stream是java8中比较重要两个新特性,lambda表达式采用一种简洁的语法定义代码块,允许我们将行为传递到函数中.之前我们想将行为传递到函数中,仅有的选择是使用匿名内部类,现在我 ...
- 巩固基础知识,从C# in depth开始
真是书到用时方恨少,平时都是完成任务,书都是看个前面几章就扔书柜了.... 今天看了博客园一篇文章<我们为什么应该坚持写博客>,很有感触,觉得人生不能得过且过,以前为了各种原因,家庭,孩子 ...
- [C# 基础知识系列]专题九: 深入理解泛型可变性
引言: 在C# 2.0中泛型并不支持可变性的(可变性指的就是协变性和逆变性),我们知道在面向对象的继承中就具有可变性,当方法声明返回类型为Stream,我们可以在实现中返回一个FileStream的类 ...
随机推荐
- 【微信小程序】动态设置图片大小
我们都知道微信小程序的组件image是用来显示图片的,它有一下几个属性:1.src 图片资源地址2.mode 图片裁剪.缩放的模式3.binderror ...
- Vue监控器watch的全面解析
前言 前面讲到了计算属性computed,这次讲的是监控器watch,主要任务就是监控变量的变化 正文 watch是一个对象,键是需要观察的表达式,值是对应回调函数.值也可以是方法名,或者包含选项的对 ...
- 智能社javascript
http://www.chuanke.com/?mod=student&act=study&courseid=91706
- Django Form 的主要内置字段介绍
修改 urls.py,添加 path('field.html', views.field), 在 templates 下创建 field.html, 内容如下: <!DOCTYPE html&g ...
- django-manage.py参数
cleanup--从数据库中删除旧数据 compilemessages--将.po文件编译为.mo以与gettext一起使用 createcachetable--为SQL缓存后端创建表 create ...
- 如何下载windows版的kubectl.exe文件
github上的下载链接,不能直接下载. https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG-1.14.md#client-b ...
- JS高阶---定时器相关
首先看几个问题: [主体] (1)定时器真的时定时执行的吗? 顺序验证: 测试结果: 接下来对上述代码做下修改,增加一个长时间工作的消耗,此时再来验证下定时器运行的精准度 结果如下: (2)定时器回调 ...
- 文件处理file handling
#1. 打开文件,得到文件句柄并赋值给一个变量 #2. 通过句柄对文件进行操作 #3. 关闭文件 #1.open函数打开文件,open找的是系统的编码gbkf = open("陈粒" ...
- thymeleaf:在一个页面中引入其它的页面
这个在jsp中很容易实现,但是springBoot不推荐使用jsp,建议使用thymeleaf,下面是在thymeleaf中引入界面的方法 1.修改配置文件 spring: mvc: static-p ...
- Spring Batch 跑批框架
SpringBatch的框架包括启动批处理作业的组件和存储Job执行产生的元数据. 如果作为一个批处理应用程序的开发人员,你暂时没有必要跟这些组件打交道, 因为它们主要为我们提供组件支持的角色,但是您 ...