C# 委托(Delegate)

  C# 中的委托(Delegate)类似于 C 或 C++ 中函数的指针。委托(Delegate) 是存有对某个方法的引用的一种引用类型变量。引用可在运行时被改变。

  委托(Delegate)特别用于实现事件和回调方法。所有的委托(Delegate)都派生自 System.Delegate 类。

  声明委托(Delegate)

  委托声明决定了可由该委托引用的方法。委托可指向一个与其具有相同标签的方法。

  例如,假设有一个委托:

  public delegate int MyDelegate (string s);

  上面的委托可被用于引用任何一个带有一个单一的 string 参数的方法,并返回一个 int 类型变量。

  声明委托的语法如下:

  delegate

  实例化委托(Delegate)

  一旦声明了委托类型,委托对象必须使用 new 关键字来创建,且与一个特定的方法有关。当创建委托时,传递到 new 语句的参数就像方法调用一样书写,但是不带有参数。例如:

  public delegate void printString(string s);

  ...

  printString ps1 = new printString(WriteToScreen);

  printString ps2 = new printString(WriteToFile);

  下面的实例演示了委托的声明、实例化和使用,该委托可用于引用带有一个整型参数的方法,并返回一个整型值。

  using System;

  delegate int NumberChanger(int n);

  namespace DelegateAppl

  {

  class TestDelegate

  {

  static int num = 10;

  public static int AddNum(int p)

  {

  num += p;

  return num;

  }

  public static int MultNum(int q)

  {

  num *= q;

  return num;

  }

  public static int getNum()

  {

  return num;

  }

  static void Main(string[] args)

  {

  // 创建委托实例

  NumberChanger nc1 = new NumberChanger(AddNum);

  NumberChanger nc2 = new NumberChanger(MultNum);

  // 使用委托对象调用方法

  nc1(25);

  Console.WriteLine("Value of Num: {0}", getNum());

  nc2(5);

  Console.WriteLine("Value of Num: {0}", getNum());

  Console.ReadKey();

  }

  }

  }

  当上面的代码被编译和执行时,它会产生下列结果:

  Value of Num: 35

  Value of Num: 175

  委托的多播(Multicasting of a Delegate)

  委托对象可使用 "+" 运算符进行合并。一个合并委托调用它所合并的两个委托。只有相同类型的委托可被合并。"-" 运算符可用于从合并的委托中移除组件委托。

  使用委托的这个有用的特点,您可以创建一个委托被调用时要调用的方法的调用列表。这被称为委托的 多播(multicasting),也叫组播。下面的程序演示了委托的多播:

  using System;

  delegate int NumberChanger(int n);

  namespace DelegateAppl

  {

  class TestDelegate

  {

  static int num = 10;

  public static int AddNum(int p)

  {

  num += p;

  return num;

  }

  public static int MultNum(int q)

  {

  num *= q;

  return num;

  }

  public static int getNum()

  {

  return num;

  }

  static void Main(string[] args)

  {

  // 创建委托实例

  NumberChanger nc;

  NumberChanger nc1 = new NumberChanger(AddNum);

  NumberChanger nc2 = new NumberChanger(MultNum);

  nc = nc1;

  nc += nc2;

  // 调用多播

  nc(5);

  Console.WriteLine("Value of Num: {0}", getNum());

  Console.ReadKey();

  }

  }

  }

  当上面的代码被编译和执行时,它会产生下列结果:

  Value of Num: 75

  委托(Delegate)的用途

  下面的实例演示了委托的用法。委托 printString 可用于引用带有一个字符串作为输入的方法,并不返回任何东西。

  我们使用这个委托来调用两个方法,第一个把字符串打印到控制台,第二个把字符串打印到文件:

  using System;

  using System.IO;

  namespace DelegateAppl

  {

  class PrintString

  {

  static FileStream fs;

  static StreamWriter sw;

  // 委托声明

  public delegate void printString(string s);

  // 该方法打印到控制台

  public static void WriteToScreen(string str)

  {

  Console.WriteLine("The String is: {0}", str);

  }

  // 该方法打印到文件

  public static void WriteToFile(string s)

  {

  fs = new FileStream("c:\\message.txt",

  FileMode.Append, FileAccess.Write);

  sw = new StreamWriter(fs);

  sw.WriteLine(s);

  sw.Flush();

  sw.Close();

  fs.Close();

  }

  // 该方法把委托作为参数,并使用它调用方法

  public static void sendString(printString ps)

  {

  ps("Hello World");

  }

  static void Main(string[] args)

  {

  printString ps1 = new printString(WriteToScreen);

  printString ps2 = new printString(WriteToFile);

  sendString(ps1);

  sendString(ps2);

  Console.ReadKey();

  }

  }

  }

  当上面的代码被编译和执行时,它会产生下列结果:

  The String is: Hello World

  本文转载自:w3cschool(编辑:雷林鹏 来源:网络)

雷林鹏分享:C# 委托(Delegate)的更多相关文章

  1. 雷林鹏分享:C# 事件(Event)

    C# 事件(Event) 事件(Event) 基本上说是一个用户操作,如按键.点击.鼠标移动等等,或者是一些出现,如系统生成的通知.应用程序需要在事件发生时响应事件.例如,中断.事件是用于进程间通信. ...

  2. 雷林鹏分享:C# 泛型(Generic)

    C# 泛型(Generic) 泛型(Generic) 允许您延迟编写类或方法中的编程元素的数据类型的规范,直到实际在程序中使用它的时候.换句话说,泛型允许您编写一个可以与任何数据类型一起工作的类或方法 ...

  3. 雷林鹏分享:C# 匿名方法

    C# 匿名方法 我们已经提到过,委托是用于引用与其具有相同标签的方法.换句话说,您可以使用委托对象调用可由委托引用的方法. 匿名方法(Anonymous methods) 提供了一种传递代码块作为委托 ...

  4. 雷林鹏分享: C# 简介

    C# 简介 C# 是一个现代的.通用的.面向对象的编程语言,它是由微软(Microsoft)开发的,由 Ecma 和 ISO 核准认可的. C# 是由 Anders Hejlsberg 和他的团队在 ...

  5. 雷林鹏分享:C# 数据类型

    C# 数据类型 在 C# 中,变量分为以下几种类型: 值类型(Value types) 引用类型(Reference types) 指针类型(Pointer types) 值类型(Value type ...

  6. 雷林鹏分享:CodeIgniter 数据库操作

    在平时项目开发过程中,除了处理那些繁琐的逻辑过程外,还有一个重要的任务就是对数据库的操作处理.这里总结下自己平时使用CI过程中使用的如何对数据库进行操作处理. 在CI框架中,我们一般会把对数据库的操作 ...

  7. 雷林鹏分享:YAF路由问题

    这2天休年假,在家宅着学习研究了YAF框架,用YAF做过APP接口的项目,但是没有用来做过WEB方面的应用.趁着这2天在家想把博客用YAF进行一下改版,目的也想进一步学习一下YAF. 在这过程中遇到不 ...

  8. 雷林鹏分享:url中加号引发的错误

    刚发现了博客的一个bug,标签页中一些标签带有空格,在url输出中使用了 urlencode 函数进行处理,导致空格被转换成了加号(+),这时通过url访问时会出现错误: 临时解决方法是在urlcod ...

  9. 雷林鹏分享:Composer 安装

    下午在安装 Laravel 框架过程中,遇到了不少问题,因为 Laravel 的安装依赖于 composer,这里就先介绍一下 composer 的安装方法: 安装方法: #下载 sudo curl ...

随机推荐

  1. MFC用串行化实现文档存储和读取功能

    在面向对象的程序设计中,一般都是用二进制文件来保存文档资料.在VC++中控制和使用文件流的方法很多,MFC程序设计中常用的有两种方法:用CFile对象存储和读取文件:利用串行化存取文件.其中用CFil ...

  2. 20154312 曾林 ExpFinal CTF Writeup

    0.写在前面 1.不合理的验证方式 2.加密与解密的对抗 3.一个SQL引发的血案 4.管理员的诟病 5.备份信息的泄露 6.svn信息泄露 7.coding 8.平衡权限的威胁 9.文件上传的突破 ...

  3. python类方法、静态方法、实例方法例子

    类方法,静态方法,普通方法 #coding=utf-8   class Foo:     def __init__(self,name):         self.name=name       d ...

  4. ant编译无法依赖rt.jar

    最近同事在用ant编译投产的时候报了一个错误: 程序包com.sun.org.apache.xml.internal.security.exceptions不存在 大致网上搜集了一下资源:具体原因是相 ...

  5. 2016NOI冬令营day2

    早上起来发现头不痛了(还是咳) : | 上午先讲自然语言处理!完全不考!完全不涉及!一开始挺有兴趣,后面就完全听不懂了 : | 后来又讲了几道IOI题目(自称只是op),然后就是  从信息熵到数据压缩 ...

  6. ELK+Kafka学习笔记之FileBeat日志合并配置输出到kafka集群

    filebeat.prospectors: - type: log               #日志输出类型   enabled: true                             ...

  7. P3435 [POI2006]OKR-Periods of Words

    P3435 [POI2006]OKR-Periods of Words 题解传送门 kmp 注意:由于题目说只要A满足是2Q的前缀,所以求的不是严格的最大循环子串(20pts) 我们需要求出的是在主串 ...

  8. 20145118 《Java程序设计》 实验报告四

    实验要求 基于Android Studio开发简单的Android应用并部署测试; 了解Android组件.布局管理器的使用: 掌握Android中事件处理机制: Android Studio安装 实 ...

  9. 20165310_获奖感想与Java阶段性学习总结

    获奖感想与Java阶段性学习总结 一.Learning By Doing ​ 在此之前,其实我并没有想到能够成为小黄杉的第一批成员之一,喜悦之余,也感受到了许多的压力.小黄杉一方面代表了老师对于我这一 ...

  10. noip 瑞士轮 - 归并

    背景 在双人对决的竞技性比赛,如乒乓球.羽毛球.国际象棋中,最常见的赛制是淘汰赛和循环赛.前者的特点是比赛场数少,每场都紧张刺激,但偶然性较高.后者的特点是较为公平,偶然性较低,但比赛过程往往十分冗长 ...