使用.NET中的Action及Func泛型委托

简介: 原文 http://www.cnblogs.com/skm-blog/archive/2013/05/24/3096294.html   委托,在C#编程中占有极其重要的地位,委托可以将函数封装到委托对象中,并且多个委托可以合并为一个委托,委托对象则可以像普通对象一样被存储、传递, 之后在任何时刻进行调用,因此,C#中函数回调机制的实现基本上依赖于委托。

原文 http://www.cnblogs.com/skm-blog/archive/2013/05/24/3096294.html

  委托,在C#编程中占有极其重要的地位,委托可以将函数封装到委托对象中,并且多个委托可以合并为一个委托,委托对象则可以像普通对象一样被存储、传递, 之后在任何时刻进行调用,因此,C#中函数回调机制的实现基本上依赖于委托。C#的delegate关键字用于声明委托,它具有将声明委托类型映射到 System.Delegate类的能力,System.Delegate类位于mscorlib.dll中,是.NET的基础核心类之一。使用 delegate关键字声明一个委托,实质上创建了System.Delegate的派生类,因此委托类型并非结构体也不是其它类型,它是一个类。一个委 托对象也就是一个类的实例。以下是Delegate类的声明:

public abstract class Delegate

Delegate是所以委托类型的基类,C#中的多播委托实际上是MulticastDelegate类,它是System.Delegate的派 生类,而本文中介绍的Action、Func泛型委托实际上都是MulticastDelegate类的派生类型。C#中当我们使用delegate关键 字声明一个委托类型时,实际上是由C#编译器根据我们声明时的方法签名帮助我们生成一个与签名匹配的,派生自MulticastDelegate的类。在 泛型大量应用之前,我们写一个C#程序的时候可能会使用delegate关键字声明许多委托类型,因为这些类型都对应于不同的方法签名。通过Visual Studio的对象浏览器查看mscorlib可以看到这两种重要的泛型委托:

imageimage

 

 

 

 

 

 

其中除了Action之外,其它的委托都是泛型的,其实就是一些泛型类。这便是.NET核心库中全部的泛型委托了。这些泛型委托分为Func、 Action中,它们借助于泛型特性,可以替代C#中几乎所有的委托类型,也就是说一般情况下,在我们的程序中不必再声明任何新的委托类型,就可以包装所 有的函数了。比如我们有两个方法:

复制代码
复制代码
public static void OtputString(string str)
{
    Console.WriteLine(str);
}

public static int Add(int a, int b)
{
    return a + b;
}
复制代码
复制代码

Func泛型委托与Action相比即多出了一个TResult类型参数,用于函数具有返回值的情况,Action泛型委托用于没有返回值的函数。当我们要获得这两个方法的委托对象时这样变可以了:

var action = new Action<string>(OtputString);
action("OutputString Invoked!");
var func = new Func<int, int, int>(Add);
var sum = func(3, 5);
Console.WriteLine(sum);

可以看见,当我们将具有返回值的函数包装成委托对象时使用Func委托,如果函数没有返回值则使用Action,核心库提供的泛型委托类型参数最短 的为0,最长的为16个。因此,Action及其泛型委托可以匹配无返回值、参数数量为0到16的任何函数。同样的,Func泛型委托可以匹配由返回值、 参数 数量在0到16个的任何函数。一般情况下,程序中函数的参数数量都不会超过16个,即使超过16个,我们可以声明新的泛型委托类型来应对

使用这些泛型委托不会有任何的性能损失,使得程序中委托的使用风格保持一致。唯一的缺点就是类型的名称无法表达具体的用途,举例来讲 EventHandler委托,我们一看名字就知道这是用于事件处理的委托。而使用Action<object,EventArgs>委托我 们则无法从名称看出这种类型的委托是何种用途。

泛型委托有替代所有其它委托的能力,到底应该使用泛型委托还是普通委托、何时使用、在哪种情况下用,可能每个人都有不同的简介,不过说到底,泛型委托能统一程序代码风格以及随处方便使用等优点是非常显著的。

强烈推荐大家看看张子阳的这篇文章:http://www.cnblogs.com/JimmyZhang/archive/2007/09/23/903360.html

目录
相关文章
|
7月前
|
存储 安全 编译器
|
7月前
|
开发框架 安全 .NET
C# .NET面试系列三:集合、异常、泛型、LINQ、委托、EF!
<h2>集合、异常、泛型、LINQ、委托、EF! #### 1. IList 接口与 List 的区别是什么? IList 接口和 List 类是C#中集合的两个相关但不同的概念。下面是它们的主要区别: <b>IList 接口</b> IList 接口是C#中定义的一个泛型接口,位于 System.Collections 命名空间。它派生自 ICollection 接口,定义了一个可以通过索引访问的有序集合。 ```c# IList 接口包含一系列索引化的属性和方法,允许按索引访问、插入、移除元素等。 由于是接口,它只定义了成员的契约,而不提供具体的实现。类似于 IEnumera
358 2
|
C++
【.Net】使用委托实现被引用的项目向上级项目的消息传递事件
在实际项目过程中,经常可能遇到被引用的项目要向上传递消息,但是又不能通过方法进行返回等操作,这个时候委托就派上用场了。以下使用委托,来实现被引用的项目向上传递消息的小教程,欢迎各位大佬提供建议。1、新增控制台项目(一般在CS架构中会用的比较多,用于跨线程传递消息使用)。此处用一个控制台项目来模拟演示使用委托进行消息事件的传递教程。
103 0
【.Net】使用委托实现被引用的项目向上级项目的消息传递事件
|
物联网 网络性能优化
阿里云物联网NET Core 客户端 CZGL.AliloTClient:9.自定义 委托事件方法
阿里云物联网NET Core 客户端 CZGL.AliloTClient:9.自定义 委托事件方法
261 15
|
物联网 网络性能优化 开发工具
.NET Core 跨平台物联网网开发:设置委托事件(二)
.NET Core 跨平台物联网网开发:设置委托事件(二)
289 0
.NET Core 跨平台物联网网开发:设置委托事件(二)
|
JSON 物联网 网络性能优化
NET Core 跨平台物联网开发 SDK属性、方法、委托、类(四)
NET Core 跨平台物联网开发 SDK属性、方法、委托、类(四)
284 0
|
3月前
|
开发框架 前端开发 JavaScript
ASP.NET MVC 教程
ASP.NET 是一个使用 HTML、CSS、JavaScript 和服务器脚本创建网页和网站的开发框架。
46 7
|
3月前
|
存储 开发框架 前端开发
ASP.NET MVC 迅速集成 SignalR
ASP.NET MVC 迅速集成 SignalR
74 0
|
4月前
|
开发框架 前端开发 .NET
ASP.NET MVC WebApi 接口返回 JOSN 日期格式化 date format
ASP.NET MVC WebApi 接口返回 JOSN 日期格式化 date format
55 0