粗看C#委托
C#的好多定义跟C艹不太相同,先来分析一下“委托”。
1. 委托的定义:
委托,可以认为是类型安全的函数指针,类型安全就是指明确定义了返回类型与参数类型,在C#代码编译时就能够确保指针传参时的安全性。
值得注意的是,委托也是一种类,在普遍的定义中,“类”表示广泛的定义,泛指一类事物,而对象则表示”类的实例”。但是委托只有一个术语,既表示“类”,也表示”实例”。
委托类的定义主要是定义它函数指针的返回值、参数类型。委托类的实例化,则是将符合委托类定义的具体函数指针交给一个实例。
2. 委托的用法:
简单的用法不加赘述,把它理解成类型安全的函数指针后就容易多了。
简单的提示则是:
public delegate string GetString();
int x = 10;
GetString testmethod = new GetString(x.ToString);
x.ToString 代表的才是函数指针,而不是 x.ToString(),它代表的只是 string 类型的返回值。
3. Action<T>与Func<T>:
在C#代码阅读中,经常发现Action<T>与Func<T>的用法。
Action<T>:这类委托表示引用一个返回类型为void的方法。例如,Action<in T1, in T2> 表示调用带2个参数的方法。
Func<T>:这类委托表示引用一个带返回类型的方法。例如,Func<in T1, out T> 表示带一个参数且有返回类型的方法,out 永远放在最后一位。
使用Action<T>与Func<T>可以一句话就包含了委托类型的定义与实例化:
class MathOperation
{
public static double MultiplyByTwo(double value)
{
var res = value * 2;
Console.WriteLine("MultiplyByTwo:{0}.", res);
return res;
} public static void ProcessAndDisplay(Func<double, double> action, double value)
{
Console.WriteLine();
Console.WriteLine("ProcessAndDisplay called with value = {0}.", value);
double res = action(value);
}
} class Program
{
static void Main(string[] args)
{
Func<double, double> MathOperations = MathOperation.MultiplyByTwo; MathOperation.ProcessAndDisplay(MathOperations, 2);
Console.ReadLine();
}
}
Func<double, double> MathOperations = MathOperation.MultiplyByTwo;
在这里就无需先 delegate double MathOperations(double value) 的声明了。
4. 多播委托
class MathOperation
{
public static double MultiplyByTwo(double value)
{
var res = value * 2;
Console.WriteLine("MultiplyByTwo:{0}.", res);
return res;
} public static double Square(double value)
{
var res = value * value;
Console.WriteLine("Square:{0}.", res);
return res; } public static void ProcessAndDisplay(Func<double, double> action, double value)
{
Console.WriteLine();
Console.WriteLine("ProcessAndDisplay called with value = {0}.", value);
double res = action(value);
}
} class Program
{
static void Main(string[] args)
{
Func<double, double> MathOperations = MathOperation.MultiplyByTwo;
MathOperations += MathOperation.Square; MathOperation.ProcessAndDisplay(MathOperations, 2);
MathOperation.ProcessAndDisplay(MathOperations, 5);
Console.ReadLine();
}
}
执行结果:
从结果可以看出,每个委托实例事实上可以包含多个方法,相当于“方法数组”,每次调用委托,都会按顺序将“方法数组”中的每个方法逐个执行过去。
要注意的是,通过一个委托调用多个方法,只要其中一个方法抛出异常,那么整个委托就会停止了。
这就是多播委托。
粗看C#委托的更多相关文章
- 粗看ES6之面向对象写法
标签: es6 在es6以前,js没有类的概念,虽然有构造函数原型的方式用来做面向对向开发,但是对于书法并不是十分友好,而且对于继承实现也不是十分友好. es6引入class constructor ...
- 粗看ES6之JSON
标签: es6 ES6新增JSON特性不是特别多,只是针对JSON某些情况下的写法上有一些优化: 当key值和value值对应变量名相同时 json对像中的方法书写 示例代码如下: <!DOCT ...
- 粗看ES6之字符串
标签: javascript es6 字符串新增特性 新增二个方法 - startsWith/endsWith 字符串模板 - 反单引号的应用 startsWith 判断字符串以是否以某某开头,返回一 ...
- 粗看ES6之数组
标签: javascript es6 数组新增方法 map(可以理解为是映射,以一定规则修改数组每一项并返回全新数组) reduce(可以理解为是汇总,一堆出来一个) filter(可以理解为过滤,筛 ...
- 粗看ES6之解构赋值
标签: javascript es6 什么是解构赋值? 示例如下: <!DOCTYPE html> <html> <head> <meta charset=& ...
- 粗看ES6之函数
标签: es6 javascript 箭头函数 ES6为了书写方便引入了函数的全新简写方式-箭头函数 <!DOCTYPE html> <html> <head> & ...
- 粗看ES6之变量
标签: javascript var定义变量面临的问题 可以重复定义 无法限制变量不可修改 无块级作用域 ES6变量定义升级 新增let定义变量 新增const定义常量 let特性 有块级作用域 不可 ...
- 匹夫细说C#:庖丁解牛聊委托,那些编译器藏的和U3D给的
0x00 前言 由于工作繁忙所以距离上一篇博客已经过去一个多月的时间了,因此决心这个周末无论如何也得写点东西出来,既是总结也是分享.那么本文主要的内容集中在了委托的使用以及内部结构(当然还有事件了,但 ...
- C#中的线程一(委托中的异步)
C#中的线程一(委托中的异步) 一.同步委托 我们平时所用的委托以同步居多,我们编写一个方法和相关委托进行演示: publicdelegatevoid DoSomethingDelegate(stri ...
随机推荐
- 简单的Goto运算演示程序
/* * 该程序用于计算某个项集的Goto集 * RexfieldVon * 2013年8月11日2:34:50 */ #include <stdio.h> #include <st ...
- zoj 3365 灵活数字规律
题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3365 #include <cstdio> #incl ...
- call, apply的用法意义以及区别是什么
call和apply没有什么大的区别,两者的作用都是:改变对象的this指向的内容. 他们的写法不同,如下: func.call(func1, var1, var2, var3); func.appl ...
- ie8下$(document).on('mouseover mouseout','ul li',function(){})的bug
$(document).on('mouseover mouseout','ul li',function(){ if (event.type == 'mouseover') { c ...
- SQL读取XML字段类型的信息
USE CSOS_NEW_2 GO --(1)定义临时表 DECLARE @table TABLE(id INT IDENTITY(1,1),XMLDetail XML) DECLARE @xml X ...
- [转] Boost智能指针——scoped_ptr
http://www.cnblogs.com/tianfang/archive/2008/09/15/1291050.html boost::scoped_ptr和std::auto_ptr非常类似, ...
- SpringMVC中文乱码
刚刚构建的SpringMVC项目,一般都是中文乱码的. 这时的工程就是一个JSP页面的事情,可以添加如下代码 <%@ page language="java" import= ...
- 《Android开发艺术探索》读书笔记 (6) 第6章 Android的Drawable
本节和<Android群英传>中的第六章Android绘图机制与处理技巧有关系,建议先阅读该章的总结 第6章 Android的Drawable 6.1 Drawable简介 (1)Andr ...
- iOS网络HTTP、TCP、UDP、Socket 知识总结
OSI 七层模型 我们一般使用的网络数据传输由下而上共有七层,分别为物理层.数据链路层.网络层.传输层.会话层.表示层.应用层,也被依次称为 OSI 第一层.第二层.⋯⋯. 第七层. 如下图: 各层功 ...
- Codeforces 245G Suggested Friends - 交集set_intersection()
一些人互相是朋友(无向图连一条无向边),现在要添加一个推荐朋友的功能,如果对于x,有y,x与y不是朋友,但是y和x有共同的朋友,并且共同的朋友最多,那么y可以推荐给x.问对于每一个人,有多少人值得推荐 ...