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

  1. 粗看ES6之面向对象写法

    标签: es6 在es6以前,js没有类的概念,虽然有构造函数原型的方式用来做面向对向开发,但是对于书法并不是十分友好,而且对于继承实现也不是十分友好. es6引入class constructor ...

  2. 粗看ES6之JSON

    标签: es6 ES6新增JSON特性不是特别多,只是针对JSON某些情况下的写法上有一些优化: 当key值和value值对应变量名相同时 json对像中的方法书写 示例代码如下: <!DOCT ...

  3. 粗看ES6之字符串

    标签: javascript es6 字符串新增特性 新增二个方法 - startsWith/endsWith 字符串模板 - 反单引号的应用 startsWith 判断字符串以是否以某某开头,返回一 ...

  4. 粗看ES6之数组

    标签: javascript es6 数组新增方法 map(可以理解为是映射,以一定规则修改数组每一项并返回全新数组) reduce(可以理解为是汇总,一堆出来一个) filter(可以理解为过滤,筛 ...

  5. 粗看ES6之解构赋值

    标签: javascript es6 什么是解构赋值? 示例如下: <!DOCTYPE html> <html> <head> <meta charset=& ...

  6. 粗看ES6之函数

    标签: es6 javascript 箭头函数 ES6为了书写方便引入了函数的全新简写方式-箭头函数 <!DOCTYPE html> <html> <head> & ...

  7. 粗看ES6之变量

    标签: javascript var定义变量面临的问题 可以重复定义 无法限制变量不可修改 无块级作用域 ES6变量定义升级 新增let定义变量 新增const定义常量 let特性 有块级作用域 不可 ...

  8. 匹夫细说C#:庖丁解牛聊委托,那些编译器藏的和U3D给的

    0x00 前言 由于工作繁忙所以距离上一篇博客已经过去一个多月的时间了,因此决心这个周末无论如何也得写点东西出来,既是总结也是分享.那么本文主要的内容集中在了委托的使用以及内部结构(当然还有事件了,但 ...

  9. C#中的线程一(委托中的异步)

    C#中的线程一(委托中的异步) 一.同步委托 我们平时所用的委托以同步居多,我们编写一个方法和相关委托进行演示: publicdelegatevoid DoSomethingDelegate(stri ...

随机推荐

  1. JavaScript 操作 DOM 常用 API 总结

    文本整理了javascript操作DOM的一些常用的api,根据其作用整理成为创建,修改,查询等多种类型的api,主要用于复习基础知识,加深对原生js的认识. 基本概念 在讲解操作DOM的api之前, ...

  2. javaweb项目的优化 - 几番思念

    简单地来看一个浏览器用户访问的流程: 浏览器->服务器->返回结果显示  这么简单地看,可能想得到的优化手段很少,常见的可能就是优化sql,加快数据库处理:加个缓存,加快返回:使用静态文件 ...

  3. Monkey log分析说明

    运行命令: adb shell monkey -p com.crazyhornets.MyHokageAndroidZSY -v -v -v 20 -- throttle 1000 Log: :Mon ...

  4. .mtl文件格式解析

    最近在导入下载的.OBJ文件,有时会出现只有模型而没有材质渲染的情况.难道材质要自己一点一点重新赋予?抓狂……我知道.OBJ文件用来存储模型信息,观察第一行代码,可以看到材质库文件为mtllib ## ...

  5. Mongodb快速入门之使用Java操作Mongodb

    [IT168 专稿]在上一篇文章中,我们学习了Mongodb的安装和初步使用,在本文中,将学习如何使用Java去编程实现对Mongodb的操作. HelloWorld程序 学习任何程序的第一步,都是编 ...

  6. 通过cocos2d-x的CCGLProgram和CCShaderCache的实现来分析OpenGL ES中的Shader编程

    在OpenGL ES中,Shader是着色器,包括两种:顶点着色器(Vertex Shader)和片元着色器(Fragment Shader).每个program对象有且仅有一个Vertex Shad ...

  7. PHP简单利用token防止表单重复提交(转)

    <?php/* * PHP简单利用token防止表单重复提交 */function set_token() { $_SESSION['token'] = md5(microtime(true)) ...

  8. debian7 安装配置

    最近几天折腾了一下Debian 7 (gnome桌面DVD版,KDE桌面CD版最后会提到),总的来说收获还是挺大的,对比以前使用ubuntu,debian 7给我的感觉像是一个新生婴儿,不带多余的花俏 ...

  9. 在 Java 中高效使用锁的技巧--转载

    竞争锁是造成多线程应用程序性能瓶颈的主要原因 区分竞争锁和非竞争锁对性能的影响非常重要.如果一个锁自始至终只被一个线程使用,那么 JVM 有能力优化它带来的绝大部分损耗.如果一个锁被多个线程使用过,但 ...

  10. 获取context path或者basePath

    转自:http://hexudonghot.blog.163.com/blog/static/532043422012112264411234/ 在jsp中获取context path或者basePa ...