C# 中的委托类似于 C 或 C++ 中的函数指针。使用委托使程序员可以将方法引用封装在委托对象内。然后可以将该委托对象传递给可调用所引用方法的代码,而不必在编译时知道将调用哪个方法。与 C 或 C++ 中的函数指针不同,委托是面向对象、类型安全的,并且是安全的。

委托声明定义一种类型,它用一组特定的参数以及返回类型封装方法。对于静态方法,委托对象封装要调用的方法。对于实例方法,委托对象同时封装一个实例和该实例上的一个方法。如果您有一个委托对象和一组适当的参数,则可以用这些参数调用该委托。

委托的一个有趣且有用的属性是,它不知道或不关心自己引用的对象的类。任何对象都可以;只是方法的参数类型和返回类型必须与委托的参数类型和返回类型相匹配。这使得委托完全适合“匿名”调用。

声明委托 以下语句:

public delegate void ProcessBookDelegate(Book book);

声明一个新的委托类型。每个委托类型都描述参数的数目和类型,以及它可以封装的方法的返回值类型。每当需要一组新的参数类型或新的返回值类型时,都必须声明一个新的委托类型。

实例化委托 声明了委托类型后,必须创建委托对象并使之与特定方法关联。与所有其他对象类似,新的委托对象用 new 表达式创建。但创建委托时,传递给 new 表达式的参数很特殊:它的编写类似于方法调用,但没有方法的参数。

下列语句:

bookDB.ProcessPaperbackBooks(new ProcessBookDelegate(PrintTitle));

创建与静态方法 Test.PrintTitle 关联的新的委托对象。下列语句:

bookDB.ProcessPaperbackBooks(new

ProcessBookDelegate(totaller.AddBookToTotal));

创建与对象 totaller 上的非静态方法 AddBookToTotal 关联的新的委托对象。在两个例子中,新的委托对象都立即传递给 ProcessPaperbackBooks 方法。

请注意一旦创建了委托,它所关联到的方法便永不改变:委托对象不可改变。

调用委托 创建委托对象后,通常将委托对象传递给将调用该委托的其他代码。通过委托对象的名称(后面跟着要传递给委托的参数,括在括号内)调用委托对象。下面是委托调用的示例:

processBook(b);

示例 2

本示例演示组合委托。委托对象的一个有用属性是,它们可以“+”运算符来组合。组合的委托依次调用组成它的两个委托。只可组合相同类型的委托,并且委托类型必须具有 void 返回值。“-”运算符可用来从组合的委托移除组件委托。

// compose.cs

using System;

delegate void MyDelegate(string s);

class MyClass

{

public static void Hello(string s)

{

Console.WriteLine(" Hello, {0}!", s);

}

public static void Goodbye(string s)

{

Console.WriteLine(" Goodbye, {0}!", s);

}

public static void Main()

{

MyDelegate a, b, c, d;

// Create the delegate object a that references

// the method Hello:

a = new MyDelegate(Hello);

// Create the delegate object b that references

// the method Goodbye:

b = new MyDelegate(Goodbye);

// The two delegates, a and b, are composed to form c,

// which calls both methods in order:

c = a + b;

// Remove a from the composed delegate, leaving d,

// which calls only the method Goodbye:

d = c - a;

Console.WriteLine("Invoking delegate a:");

a("A");

Console.WriteLine("Invoking delegate b:");

b("B");

Console.WriteLine("Invoking delegate c:");

c("C");

Console.WriteLine("Invoking delegate d:");

d("D");

}

}

输出

Invoking delegate a:

Hello, A!

Invoking delegate b:

Goodbye, B!

Invoking delegate c:

Hello, C!

Goodbye, C!

Invoking delegate d:

Goodbye, D!

委托和事件

委托非常适合于用作事件(从一个组件就该组件中的更改通知“侦听器”)。

委托与接口

委托和接口的类似之处是,它们都允许分隔规范和实现。多个独立的作者可以生成与一个接口规范兼容的多个实现。类似地,委托指定方法的签名,多个作者可以编写与委托规范兼容的多个方法。何时应使用接口,而何时应使用委托呢?

委托在以下情况下很有用:

调用单个方法。

一个类可能希望有方法规范的多个实现。

希望允许使用静态方法实现规范。

希望类似事件的设计模式。

调用方不需要知道或获得在其上定义方法的对象。

实现的提供程序希望只对少数选择组件“分发”规范实现。

需要方便的组合。

接口在以下情况下很有用:

规范定义将调用的一组相关方法。

类通常只实现规范一次。

接口的调用方希望转换为接口类型或从接口类型转换,以获得其他接口或类。

http://blog.csdn.net/wobuwei/archive/2008/07/25/2708186.aspx

转载于:https://www.cnblogs.com/alexusli/archive/2008/10/15/1312013.html

delegate(转)相关推荐

  1. 理解委托(delegate)及为什么要使用委托

    委托:是一种定义方法签名的类型. 当实例化委托时,您可以将其实例与任何具有兼容签名的方法相关联. 您可以通过委托实例调用方法. 上述为官方说法,理解起来比较难,举个生活中的例子: 某人有三子,让他们各 ...

  2. swift中delegate与block的反向传值

    swift.jpg 入门级 此处只简单举例并不深究,深究我也深究不来.对于初学者来说delegate或block都不是一下子能理解的,所以我的建议和体会就是,理不理解咱先不说,我先把这个格式记住,对就 ...

  3. 在请求完成后回调delegate的方法。然而回调时经常遇到这种情况:delegate已经被释放...

    最近的项目遇到了网络请求,需要在请求完成后回调delegate的方法.然而回调时经常遇到这种情况:delegate已经被释放,这时调用其方法则会引起crash. objc的runtime中有两种判断类 ...

  4. 异步使用委托delegate --- BeginInvoke和EndInvoke方法

    当我们定义一个委托的时候,一般语言运行时会自动帮委托定义BeginInvoke 和 EndInvoke两个方法,这两个方法的作用是可以异步调用委托. 方法BeginInvoke有两个参数: Async ...

  5. 对delegate进行扩展 打造通用的计时完成方法

    连接数据库是程序员经常要做的事情, 通常情况下, 需要连接SQL Server中哪个数据库是已知的, 用户在输入SQL Server的服务器IP.用户名.密码和数据库名字后, 如果所有信息输入正确, ...

  6. Swift - 委托(delegate)的介绍,及使用样例

    1,委托的说明 委托(delegate)是Cocoa的一个术语,表示将一个对象的部分功能转交给另一个对象. 比如对象A希望对象B知道将要发生或已经发生某件事情,对象A可以把对象B的引用存为一个实例变量 ...

  7. C#中Action与delegate、EventHandler的差异

    Action是一个泛型的委托,其内部即使用delegate去实现,当普通的delegate定义的参数与Action个数.类型一致时,两者实现的功能是一样的.只是Action的方式更加简洁.规范.如下: ...

  8. 【转】iOS开发-Protocol协议及委托代理(Delegate)传值

    原文网址:http://www.cnblogs.com/GarveyCalvin/p/4210828.html 前言:因为Object-C是不支持多继承的,所以很多时候都是用Protocol(协议)来 ...

  9. c# 带返回值的action_C#知识点讲解之C#delegate、event、Action、EventHandler的使用和区别...

    今天来讲一讲<C#delegate.event.Action.EventHandler的使用和区别> 目录 所以,event应运而生 所以,EventHandler应运而生 所以,Acti ...

  10. iOS视图控制器之间delegate传值

    2019独角兽企业重金招聘Python工程师标准>>> // ** *为了从ViewControllerB往回传值到ViewControllerA,我们需要使用协议(Protocol ...

最新文章

  1. webfocus在移动终端上的应用DEMO
  2. 计算机组成计算题中的术语,计算机组成原理习题——日常记录
  3. 大数据与智能算法(三-集疏运应用)-SMU在线学习笔记
  4. 手动安装 SAP Spartacus 3.3.0版本并启用服务器端渲染 SSR
  5. (四面体)CCPC网络赛 HDU5839 Special Tetrahedron
  6. http://jingyan.baidu.com/article/2009576193ee38cb0721b416.html
  7. MFC中新建类在classview中没有显示问题
  8. 旋转立方体(opengl)
  9. 计算机没鼠标怎么,电脑没鼠标怎么开启系统
  10. ZEGO 自研客户端配置管理系统 —— 云控
  11. [RPA之家]UiPath程序设计文档
  12. 利用F12下载网页高清图像
  13. SwiftUI SF Symbols 好处及其使用指南
  14. 速度测试(speed test)
  15. 机器学习特征工程之特征缩放+无量纲化:行归一化(范数化,Normalizer)
  16. 高斯过程动态模型(GPDM)简析
  17. php代码出现notice,PHP提示Notice: Undefined variable的解决办法
  18. PHP微信开发素材管理,PHP微信开发包,微信开发SDK
  19. jquery 输入框失去焦点时 (blur)事件
  20. java timestamp 使用_Java中针对Timestamp的操作解析

热门文章

  1. jar命令成功完成 java -jar 命令却提示“没有主清单属性”!
  2. 【生信进阶练习1000days】day22-复习day1~day14的知识点
  3. 数值计算详细笔记(一):基础数学知识回顾
  4. 不写xml的MyBatis-Plus中关联属性的查询(1对1,1对n)
  5. java字符串查找算法_java – 查找所有“字符相等”字符串的高效算法?
  6. [bzoj2932][POI1999]树的染色问题
  7. jQuery----分页插件实现
  8. [您有新的未分配科技点][BZOJ3545BZOJ3551]克鲁斯卡尔重构树
  9. 01背包 hihocoder第六周
  10. UIView中的坐标转换