基础知识---委托和 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的类 ...
随机推荐
- java都是值传递,没有引用传递
博主这几天在复习 javaSE 部分的内容时,遇到了关于参数传值的问题,但是始终不知道原因,上网上一查才知道钻牛角尖了,把C语言的参数传值转移到java中了. 相信很多在学习java之前,有接触过C/ ...
- java斐波那契数列的顺序输出
斐波那契数列,即1.1.2.3.5......,从第三个数开始包括第三个数,都为这个数的前两个数之和,而第一第二个数都为1. 下面是java输出斐波那契数列的代码: import java.util. ...
- skipped obstructing working copy
svn update时报错,处理方法,将报错的文件夹压缩备份一下,然后删除报错的文件夹,重新update即可.
- Django Windows+IIS+wfastcgi 环境下部署
教程基于 Windows 10专业版 + Python3.6 + IIS + wfastcgi 之上部署Django2.2的,同样适用于Windows server2012服务器和Windows7及以 ...
- eclipse打可运行的jar
参考:https://www.cnblogs.com/wangzhisdu/p/7832666.html 用eclipse打包可运行的jar比较坑的地方: 3.1 从下拉框选择该jar的入口文件,即m ...
- 01-numpy-笔记-empty
import numpy as np >>> a = np.empty([2,3]) >>> a array([[0.00000000e+000, 4.935933 ...
- 京东框架jd_frame
#!/user/bin/python# -*- coding:utf-8 -*-#1.定义京东首页def index(): pass#2.定义加目录def home(): pass#3.定义购物车功能 ...
- OpenStack产品摘要
docs OpenStack 核心服务 计算 Nova:虚拟化设施资源管理 ZUN:容器管理 QINLING:Serveless Function 裸金属 IRONIC:裸金属资源管理 CYBORDF ...
- zz深度学习论文合集大全
Pull requestsIssues Marketplace Explore Learn Git and GitHub without any code! Using ...
- luoguP4551最长异或路径
P4551最长异或路径 链接 luogu 思路 从\(1\)开始\(dfs\)求出\(xor\)路径.然后根据性质\(x\)到\(y\)的\(xor\)路径就是\(xo[x]^xo[y]\) 代码 # ...