CLR之委托的揭秘(二)
杂谈
在开始真正的代码之前,分析一下上周的一些工作内容,发现自己在代码上还是有很多小毛病需要纠正和去更改的,首先之前一直疏于文档的整理,几乎很少去写文档,第二对于接口开发过程中缺少一定的严谨性,很多问题没有考虑清楚就已经代码敲完了,其实应该先针对接口去写一份接口说明文档,一方面提升自己的文档能力,另外一方面也通过文字整理自己的思路,还有就是程序开发中不能懒,因为懒已经出了很多问题,程序毕竟是严谨的,你忽能它,它也必然忽能你!
这是上周工作中的一些总结,接下来继续以CLR的角度分析委托,上一节说了委托的定义,委托链,还有匿名委托。接下来我们分析
泛型委托
其实我对于泛型委托之前也是完全一知半解,有一次在用Linq的时候,先用了Where有用了Find,我的本意是先筛选在查找,但实际上两者基本上是一回事,都是泛型委托,当然关于泛型委托不得不说的就是 Action<T> 泛型委托, Func<T, TResult>,两者是有区别的
Action<T> 泛型委托:封装一个方法,该方法只采用一个参数并且不返回值。可以使用此委托以参数形式传递方法,而不用显式声明自定义的委托。该方法必须与此委托定义的方法签名相对应。也就是说,封装的方法必须具有一个通过值传递给它的参数,并且不能返回值。当然泛型委托不只是只能支持一个参数,它最多可以支持四个参数。
Func<T, TResult> 委托:封装一个具有一个参数并返回 TResult 参数指定的类型值的方法。同理,这里的泛型委托只是接受一个参数的委托,它最多同样支持四个参数。TResult:此委托封装的方法的返回值类型。
Action T
还记得上一篇文章中我们关于委托的定义和声明中,是如何要求的么?委托的安全性非常高,所以在声明委托时,要声明委托返回的类型和参数类型,但是在 Action<T> 上,我们不需要如此,接下来看一下普通声明和Action<T> 声明的委托有什么不同
/*
泛型委托和普通委托的声明对比
1.不需要使用delegate关键字
2.Action只能使用返回值为void的方法,如果返回值具有对象类型则报错
*/
delegate void DisplayMessage(string message);
static void Main(string[] args)
{ DisplayMessage messageTarget;
messageTarget = ShowWindowsMessage;
messageTarget("Hello, World!"); Action<string> messageTarget1;
messageTarget1 = ShowWindowsMessage;
messageTarget1("泛型委托");
}
public static void ShowWindowsMessage(string s) {
Console.WriteLine(s);
}
我在注释里加入了一行解释:不需要使用delegate关键字,为什么 Action<T> 可以直接声明使用呢?这和其自身封装有关,下面代码就是其在系统中的封装,可以看出来,Action在元数据中就已经存在了public delegate void封装,明确了其使用的范围
//
// 摘要:
// 封装一个方法,该方法只有一个参数并且不返回值。
//
// 参数:
// obj:
// 此委托封装的方法的参数。
//
// 类型参数:
// T:
// 此委托封装的方法的参数类型。此类型参数是逆变。即可以使用指定的类型或派生程度更低的类型。有关协变和逆变的更多信息,请参见泛型中的协变和逆变。
public delegate void Action<in T>(T obj);
Func<T, TResult>
关于Func<T, TResult> 委托,和 Action<T> 委托的区别最大点在于Func<T, TResult>支持返回类型,刚才我们看了 Action<T> 以后会觉得 Action<T> 只能用于void方法,那么如果方法返回int, Action<T> 是不是就不能用了?对的,不能用了。
Func<T,TResult> 的表现形式分为以下几种:
1。Func<T,TResult>
2。Func<T,T1,TResult>
3。Func<T,T1,T2,TResult>
4。Func<T,T1,T2,T3,TResult>
5。Func<T,T1,T2,T3,T4,TResult>
其实以上的几种表现形式就是Func<T,TResult>的几种重载,最多支持四个参数的重载,分别说一下各个参数的意义,TResult表示 委托所返回值 所代表的类型, T,T1,T2,T3,T4表示委托所调用的方法的参数类型,
以下是使用示例:
/*
使用普通委托和泛型委托同样完成一个返回值为string,参数为int方法的委托调用
*/
delegate string DisplayMessage(int message);
static void Main(string[] args)
{
DisplayMessage messageTarget;
messageTarget = Kuadi;
Console.WriteLine(messageTarget());
//Func<T,TResult>
Func<int,string> messageTarget1;
messageTarget1 = Kuadi;
Console.WriteLine(messageTarget1());
}
public static string Kuadi(int zhong) {
if (zhong == )
return "你的快递";
else
return "没有你的货";
}
可以看的出来,泛型委托实际上比起普通委托最大好处就是可以少些很多代码,在以后的代码中可以用泛型委托完成的就不需要使用普通委托去完成,刚才文章中提到了一个委托在linq中得使用,那么linq中如何体现的Action<T> 泛型委托和 Func<T, TResult>泛型委托的呢
Linq中的泛型委托使用
namespace System.Linq
{
public static class Enumerable
{
public static IEnumerable<TSource> Where<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate);
}
}
由于Linq中的方法实在有点多,今天我们只看一下Where,当然具体实现是看不到,但是我们在这串代码中却看到了一个身影Func<TSource, bool>这实际上涉及了linq的内部另一个方法的调用,这串代码所做的事就是把条件作为一个参数传给predicate调用其内部方法,最终返回一个bool值。
当然了委托用在Liqn中不只是这么一个地方,还有很多地方都用到了委托,感兴趣的小伙伴可以研究一下,委托在LInq中的使用
CLR之委托的揭秘(二)的更多相关文章
- CLR之委托的揭秘(一)
初识委托: 在之前的学习中我们已经可以把对象,值,数组当作参数传递给方法,但是有没有可能把方法也当作参数传递给方法呢?有了这个想法于是就有了委托.方法当作一种参数去传递,但是方法有的 ...
- 解密jQuery事件核心 - 委托设计(二)
第一篇 http://www.cnblogs.com/aaronjs/p/3444874.html 从上章就能得出几个信息: 事件信息都存储在数据缓存中 对于没有特殊事件特有监听方法和普通事件都用ad ...
- C++模拟C#事件委托机制(二)
原文 来自于http://www.cnblogs.com/netssfy/archive/2010/02/02/1662056.html 为了解决非法地址访问的冲突,首先需要知道发生该错误的原因是什么 ...
- CLR via C#读书笔记二:类型基础
1.CLR允许将对象转换为它的(实际)类型或者它的任何基类型. 2.is操作符检测对象是否兼容于指定类型,is操作符永远不抛出异常. 3.as操作符返回对同一个对象的非null引用.如果对象不兼容,a ...
- C#编程之委托与事件四(二)【转】
C#编程之委托与事件(二) 我在上一篇文章(C#编程之委托与事件(一) )中通过示例结合的方法介绍了委托,在本文中,我同样以代码示例的方式来介绍C#里的事件机制. 二.事件 1.了解概 ...
- 转载——CLR标量函数、表值函数和聚合函数(UDA)
本节主要介绍使用CLR创建标量函数,表值函数和聚合函数. 所谓标量函数指的就是此函数只返回一个值.表值函数返回值是一个表.聚合函数是在select语句中使用的,用来聚合一个结果集,类似于Sum()或是 ...
- .NET基础拾遗(4)委托和事件1
一.委托初窥:一个拥有方法的对象 (1)本质:持有一个或多个方法的对象:委托和典型的对象不同,执行委托实际上是执行它所“持有”的方法. (2)如何使用委托? ①声明委托类型(delegate关键字) ...
- ios协议和委托
在iPhone开发协议和委托是常接触到的东西,到底什么是协议什么是委托,他们什么关系? 一 协议 (1)协议相当于没有与类相关联的接口,他申明一组方法,列出他的参数和返回值,共享给其他类使用,然后不进 ...
- 大话C#之委托
开篇先来扯下淡,上篇博客LZ在结尾说这篇博客会来说说C#中的事件.但是当LZ看完事件之后发现事件是以委托为基础来实现的,于是LZ就自作主张地在这篇博客中先来说说委托,还烦请各位看官见谅!!!另外关于委 ...
随机推荐
- zabbix基本操作
zabbix基本操作 ---- 2016年终总结 二 包括的内容: 添加主机 查看监控数据 添加监控项 创建触发器 创建模版 添加报警 添加媒介 添加主机 进入页面 点击Configuration(大 ...
- Excel导出插件
前言 一个游戏通常需要10多个Excel表格或者更多来配置,一般会通过导出csv格式读取配置. 本文提供导出Excel直接生成c#文件,对应数据直接生成结构体和数组,方便开发排错和简化重复写每个表格的 ...
- SQL server 数据库备份大
首先简单的介绍一下Sql server 备份的类型有: 1:完整备份(所有的数据文件和部分的事务日志文件) 2:差异备份(最后一次完成备份后数据库改变的部分) 3:文件和文件组备份(对指定的文件和文件 ...
- 张高兴的 Windows 10 IoT 开发笔记:DHT11 温湿度传感器
GitHub : https://github.com/ZhangGaoxing/windows-iot-demo/tree/master/DHT11Demo
- Fiddler使用总结(一)
与后端数据通信是前端日常开发的重要一环,在与后端接口联调的时候往往需要通过查看后端返回的数据进行调试.如果在PC端,Chrome自带的DevTools就已经足够用了,Network面板可以记录所有网络 ...
- Node.js之异步流控制
前言 在没有深度使用函数回调的经验的时候,去看这些内容还是有一点吃力的.由于Node.js独特的异步特性,才出现了"回调地狱"的问题,这篇文章中,我比较详细的记录了如何解决异步流问 ...
- RabbitMQ 笔记-RPC
RabbitMQ中实现RPC的机制是: 客户端发送请求(消息)时,在消息的属性(MessageProperties,在AMQP协议中定义了14中properties,这些属性会随着消息一起发送)中设置 ...
- Java基础总结--泛型总结
-----泛型------JDK1.5出现的机制1.泛型出现的原因--简化书写,提高安全性技术的由来是为了解决问题,现在存在该问题,所有的容器定义类型为Object,所以任何对 象均可以放入容器--进 ...
- c# Invoke和Begininvoke区别
一.对Invoke和Begininvoke的认识 1.Invoke():同步委托,会阻塞当前主线程的运行,等待invoke()方法返回才执行后面的代码: 2.Begininvoke():异步委托,调用 ...
- swift 上的 lazy
lazy顾名思义就是慢吞吞的,万非得一就不动. 那么一个变量也是如此,只有你第一次使用的时候才进去加载.所有又称为延迟加载,需要的时候才加载. ========= 这样做的好处: 1. 模块化,把对象 ...