c#代理的使用主要在:需要将一个方法当做参数传递到另一个方法时。

比如启动一个线程执行任务,而这个线程要执行的方法可以通过代理传递过来。

代理包括一个方法或者多个方法的地址和C++的函数指针很相似,但它是类型安全的。

1.声明代理

delegate void IntMethodInvoker(int x);

这个代理可以引用返回值类型为空,有一个参数的所有方法,很重要的一点需要知道delegate是类型安全的。

delegate double TwoLongsOp(long first, long second);

有两个参数返回值为double的代理。

delegate string GetAString();

没有参数返回值为string的代理。

public delegate string GetAString();

还可以说明代理的访问权限。

2.使用代理

使用代理必须先要实例化一个代理

pri v a te delegate string GetAString();
static void Main()
{
int x = 40;
GetAString firstStringMethod = new GetAString(x.ToString); //实例化一个代理,并把该代理指向x.tostring();
Console.WriteLine("String is {0}", firstStringMethod()); //firstStringMethod()成为x.tostring()代表(代理)
// With firstStringMethod initialized to x.ToString(),
// the above statement is equivalent to saying
// Console.WriteLine("String is {0}", x.ToString());
}

可以通过以下两种方法来调用已经实例化的方法

firstStringMethod();
firstStringMethod.Invoke();

当然在实例化一个代理的时候并传递方法也可以通过以下两种形式

GetAString firstStringMethod = new GetAString(x.ToString);

GetAString firstStringMethod = x.ToString;

请看下面代理实例

class mathOperation
    {
        public static double MultiplyByTwo(double value)
        {
            return value * 2;
        }

public static double Square(double value)
        {
            return value * value;
        }
    }

定义一个方法,该方法有两个静态函数,分别用于计算值得倍数和值的平方。

class Program
    {
        delegate double DoubleOp(double x);  //定义代理用于代理相应的方法
        static void Main(string[] args)
        {
            DoubleOp[] operations =
            {
                mathOperation.MultiplyByTwo,
                mathOperation.Square
            }; //实例化一个代理数组,第一个数组元素代理MultiplyByTwo方法第二个数组元素代理Square方法
            for(int i =0 ; i < operations.Length;i++)
            {
                Console.WriteLine("Using operations[{0}]:", i);
                ProcessAndDisplayNumber(operations[i], 2.0);
                ProcessAndDisplayNumber(operations[i], 7.94);
                ProcessAndDisplayNumber(operations[i], 1.414);
                Console.WriteLine();
            }

}

static void ProcessAndDisplayNumber(DoubleOp action,double value) //代理作为参数进行传输
        {
            double result = action(value);
            Console.WriteLine("Value is {0} , result of operation is {1}", value, result);
        }
    }

二、如果不想定义代理类型而使用代理可以使用下列代理形式

Action<T> and Func<T> Delegates

action<T>指向没有返回类型的方法,可以传递16个参数,其形式如下:

Action<in T> 指向一个参数的方法

Action<in T1, in T2> 指向两个参数的方法

Action<inT1, in T2, in T3, in T4, in T5, in T6, in T7, in T8> 指向八个参数的方法

Func<T> 最多也可以传递16个参数,并且具有返回值类型

Func<out TResult> 指向没有参数,有一个返回值类型的方法。

Func<in T, out TResult> 指向一个参数的方法

Func<in T1, inT2, in T3, in T4, out TResult> 指向一个具有四个参数的方法。

1、应用举例

在上面的实例中我们定义了一个代理来指向静态方法如下形式

delegate double DoubleOp(double x);

如果不想自己定义代理,可以使用如下形式来指向静态函数的两个方法

Func<double, double>[] operations =
{
 MathOperations.MultiplyByTwo,
 MathOperations.Square
};  //使用func<double, double> 来指向有返回值类型的一个参数。并不需要自己再自定代理,而使用系统自带的代理方法。

把这个代理作为参数传递给相应的方法,其格式如下

static void ProcessAndDisplayNumber(Func<double, double> action,double value) //第一个参数是代理实例,第二个参数是代理所用到的参数值
{
double result = action(value);
Console.WriteLine("Value is {0}, result of operation is {1}",
value, result);
}

读书笔记之C# delegate的更多相关文章

  1. 《C#图解教程》读书笔记之二:存储、类型和变量

    本篇已收录至<C#图解教程>读书笔记目录贴,点击访问该目录可获取更多内容. 一.类型初窥:掀起你的盖头来 (1)C程序是一组函数和数据类型,C++程序是一组函数和类,而C#程序是一组类型声 ...

  2. 《C#图解教程》读书笔记之五:委托和事件

    本篇已收录至<C#图解教程>读书笔记目录贴,点击访问该目录可获取更多内容. 一.委托初窥:一个拥有方法的对象 (1)本质:持有一个或多个方法的对象:委托和典型的对象不同,执行委托实际上是执 ...

  3. 《编写高质量代码--Web前端开发修炼之道》读书笔记

    前言 这两周参加公司的新项目,采用封闭式开发(项目成员在会议室里开发),晚上加班到很晚,所以没时间和精力写原创博客了,今天就分享下这篇<编写高质量代码--Web前端开发修炼之道>读书笔记吧 ...

  4. Essential C#读书笔记

    Essential C#读书笔记 这是一个多变的时代,一次又一次的浪潮将不同的人推上了巅峰.新的人想搭上这一波,同时老的人也不想死在沙滩上.这些年新的浪潮又一次推开,历史不停地重复上演,那便是移动互联 ...

  5. Spring读书笔记——bean解析

    前情回顾 上篇<Spring读书笔记--bean加载>我们从代码角度介绍了有哪些类负责解析XML文件,又是如何一步步从XML格式脱变成我们熟悉的bean的,直到DefaultBeanDef ...

  6. Spring读书笔记——bean创建(上)

    通过<Spring读书笔记--bean加载>和<Spring读书笔记--bean解析>,我们明白了两件事. Spring如何加载消化一个xml配置文件 Spring如何将xml ...

  7. 《C#从现象到本质》读书笔记(六)第8章委托和事件

    <C#从现象到本质>读书笔记(六)第二部分 C#特性 第8章委托和事件 从这一部分开始,知识点就相对少了,重要的是代码练习.奈何太高深的代码平常不怎么用,这些特性也不是经常写代码的. 委托 ...

  8. 《软件测试自动化之道》读书笔记 之 基于反射的UI测试

    <软件测试自动化之道>读书笔记 之 基于反射的UI测试 2014-09-24 测试自动化程序的任务待测程序测试程序  启动待测程序  设置窗体的属性  获取窗体的属性  设置控件的属性  ...

  9. 《软件测试自动化之道》读书笔记 之 XML测试

    <软件测试自动化之道>读书笔记 之 XML测试 2014-10-07 待测程序测试程序  通过XmlTextReader解析XML  通过XmlDocument解析XML  通过XmlPa ...

随机推荐

  1. UIView类绘图出现错误提示

    一:问题: Jan 16 15:49:53  CUBOT Band Ⅲ[2082] <Error>: CGContextSetLineWidth: invalid context 0x0. ...

  2. Ubuntu 16 04 安装KVM

    apt-get install qemu-kvm ubuntu-vm-builder bridge-utils http://www.linuxidc.com/Linux/2016-06/132188 ...

  3. Python操作redis、memcache和ORM框架_Day13

    一.memcache Memcached 是一个高性能的分布式内存对象缓存系统,用于动态Web应用以减轻数据库负载.它通过在内存中缓存数据和对象来减少读取数据库的次数,从而提高动态.数据库驱动网站的速 ...

  4. HTML5学习总结——HTML5入门与新增标签

    一.HTML5概要 1.1.为什么需要HTML5 概念: HTML5 是继 HTML4.01, XHTML 1.0 和 DOM 2 HTML 后的又一个重要版本, 旨在消除富 Internet 程序( ...

  5. Webservice WCF WebApi

    注明:改编加组合 在.net平台下,有大量的技术让你创建一个HTTP服务,像Web Service,WCF,现在又出了Web API.在.net平台下,你有很多的选择来构建一个HTTP Service ...

  6. Hex Workshop(16进制编辑利器) 6.7.2绿色版

    软件名称: Hex Workshop 6.7.2绿色版(16进制编辑利器) 软件语言: 简体中文 授权方式: 免费软件 运行环境: Win 32位/64位 软件大小: 1.8MB 图片预览: 软件简介 ...

  7. 【 Note 】GDB调试

    GDB是在linux下的调试功能 命令: 启动文件: 普通调试 gdb 可执行文件 分屏调试 gdb -tui 可执行文件 ->调试: 运行 r 设置断点 b 删除断点 delete 断点编号 ...

  8. vlc-android1.8.0的全部源代码[包括C语言]

    我们基于vlc,整理出了vlc-android1.8.0的全部源代码, 并增加了LibVLC的简单调用, 您只需要7行代码,就可以完成调用,和原生的MediaPlayer类似. 下载地址https:/ ...

  9. PHPStorm 安装 SASS、SCSS + Compass

    许久没更新博客啦,这两天研究了下 SASS 和 LESS ,最终选了 SASS,因为相对比较成熟些吧,试了很多坑之后,终于成功了,下面上步骤: 1. 安装 PHPStorm 的 SASS 插件 好像是 ...

  10. MyBatis学习-映射文件标签篇(select、resultMap)

    MyBatis 真正的核心在映射文件中.比直接使用 JDBC 节省95%的代码.而且将 SQL 语句独立在 Java 代码之外,可以进行更为细致的 SQL 优化. 一. 映射文件的顶级元素 selec ...