委托定义类型,类型指定特定方法签名。 可将满足此签名的方法(静态或实例)分配给该类型的变量,然后(使用适当参数)直接调用该方法,或将其作为参数本身传递给另一方法再进行调用。 以下示例演示了委托的用法。

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的更多相关文章

  1. C# 基础知识系列- 6 Lambda表达式和Linq简单介绍

    前言 C#的lambda和Linq可以说是一大亮点,C#的Lambda无处不在,Linq在数据查询上也有着举足轻重的地位. 那么什么是Linq呢,Linq是 Language Intergrated ...

  2. 《Java基础知识》Java Lambda表达式

    接触Lambda表达式的时候,第一感觉就是,这个是啥?我居然看不懂,于是开始寻找资料,必须弄懂它. 先来看一个案例: @FunctionalInterface public interface MyL ...

  3. C#基础知识之事件和委托

    本文中,我将通过两个范例由浅入深地讲述什么是委托.为什么要使用委托.委托的调用方式.事件的由来..Net Framework中的委托和事件.委托和事件对Observer设计模式的意义,对它们的中间代码 ...

  4. C#基础知识---Lambda表达式

    一.Lambda表达式简介 Lambda表达式可以理解为匿名函数,可以包含表达式和语句.它提供了一种便利的形式来创建委托. Lambda表达式使用这个运算符--- "=>", ...

  5. [C# 基础知识系列]专题一:深入解析委托——C#中为什么要引入委托

    转自http://www.cnblogs.com/zhili/archive/2012/10/22/Delegate.html 引言: 对于一些刚接触C# 不久的朋友可能会对C#中一些基本特性理解的不 ...

  6. C#基础加强篇—委托、Lambda表达式和事件(下)

    3.事件 事件作为C#中的一种类型,为类和类的实例定义发出通知的能力,从而将事件和可执行代码捆绑在了一起.事件是对象发送的消息,以发信号通知操作的发生.操作可能是由用户交互引起的,也可能是由某些其他的 ...

  7. JAVA基础知识|lambda与stream

    lambda与stream是java8中比较重要两个新特性,lambda表达式采用一种简洁的语法定义代码块,允许我们将行为传递到函数中.之前我们想将行为传递到函数中,仅有的选择是使用匿名内部类,现在我 ...

  8. 巩固基础知识,从C# in depth开始

    真是书到用时方恨少,平时都是完成任务,书都是看个前面几章就扔书柜了.... 今天看了博客园一篇文章<我们为什么应该坚持写博客>,很有感触,觉得人生不能得过且过,以前为了各种原因,家庭,孩子 ...

  9. [C# 基础知识系列]专题九: 深入理解泛型可变性

    引言: 在C# 2.0中泛型并不支持可变性的(可变性指的就是协变性和逆变性),我们知道在面向对象的继承中就具有可变性,当方法声明返回类型为Stream,我们可以在实现中返回一个FileStream的类 ...

随机推荐

  1. Mysql、Oracle、SQLServer等数据库参考文档免费分享下载

    场景 MySQL 是最流行的关系型数据库管理系统,在 WEB 应用方面 MySQL 是最好的 RDBMS(Relational Database Management System:关系数据库管理系统 ...

  2. warning: Unexpected unnamed function (func-names)

    warning: Unexpected unnamed function (func-names) 看到这个提示基本是就是说你的函数不能是匿名函数,最好可以起一个名字,然后你增加一个函数名称就好了 R ...

  3. ucoreOS_lab2 实验报告

    所有的实验报告将会在 Github 同步更新,更多内容请移步至Github:https://github.com/AngelKitty/review_the_national_post-graduat ...

  4. 【IDE_IntelliJ IDEA】IDEA中使用Junit插件自动创建测试用例到test目录

    第一步 从插件资源库中搜索JunitGenerator V2.0插件并安装 第二步 配置测试用例的生成目录 1.打开File->Settings 2.搜索junit,找到JUnit Genera ...

  5. 阿里云部署SSL证书

    查找中间证书 为了确保兼容到所有浏览器,我们必须在阿里云上部署中间证书,如果不部署证书,虽然安装过程可以完全也不会报错,但可能导致Android系统,Chrome 和 Firefox等浏览器无法识别. ...

  6. (转)linux内核虚拟文件系统浅析【转】

    转自:https://www.cnblogs.com/woainilsr/p/3590716.html 转自http://hi.baidu.com/_kouu/item/4e9db8758032824 ...

  7. 06点击事件 tabBar配置 拨打电话

    1== D:\wxxm 项目的地址 2==>tabBar在全局配置中 在pages的同级目录下创建images本地图标 (最好的是在远程获取img 因为微信是有大小限制的) selectedIc ...

  8. re 模块详解

    1.re 模块 regex 1.查找 :findall 意思"匹配所有,每一项都是列表的组成元素" 有返回值 import re ret=re.findall("\d+& ...

  9. 新建Springboot项目

    软件为sts软件 1.新建项目 2.工程名称 3.选择依赖项,可以在搜索框中搜索 4.添加端口号 5.创建controller 6.创建controller类,并输入一下内容 package com. ...

  10. ASP.NET CoreMVC 中的视图

    ASP.NET Core MVC 中的视图 MVC 中的视图 用于显示Controller提供给它的 Model 的业务数据. 视图是带有嵌入 Razor 标记的 HTML 模板. 如果编程语言是 C ...