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. Java实现递归将嵌套Map里的字段名由驼峰转为下划线

    摘要: 使用Java语言递归地将Map里的字段名由驼峰转下划线.通过此例可以学习如何递归地解析任意嵌套的List-Map容器结构. 难度:初级 概述 在进行多语言混合编程时,由于编程规范的不同, 有时 ...

  2. linux常用命令:crontab 命令

    前一天学习了 at 命令是针对仅运行一次的任务,循环运行的例行性计划任务,linux系统则是由 cron (crond) 这个系统服务来控制的.Linux 系统上面原本就有非常多的计划性工作,因此这个 ...

  3. python退出多重循环

    假设一段python程序有多重循环,我们都知道在一个循环当中,用break是退出当前的循环,然后继续下一次循环,但是如何才能跳出多重循环呢,实际就是结束所有的循环. 思路1::可以定义一个异常类,在需 ...

  4. thinkphp标签实现bootsrtap轮播carousel实例

    thinkphp标签实现bootsrtap轮播carousel实例由于轮播carousel第一个div需要设置active样式才能正常显示,上面的圆点也同样需要数字,使用volist标签在循环的同时可 ...

  5. 2016NOI冬令营day1

    感冒了!!!: ( 上午听 picks 讲多项式导论(所有内容均不考)只听懂了那个O(n1.585)的多项式乘法算法 : ( 安装好了弹幕!太厉害了(有电脑的都在刷弹幕) :  ( 中午吃的不错 : ...

  6. Vue源码解析之nextTick

    Vue源码解析之nextTick 前言 nextTick是Vue的一个核心功能,在Vue内部实现中也经常用到nextTick.但是,很多新手不理解nextTick的原理,甚至不清楚nextTick的作 ...

  7. 【翻译】std::list::remove - C++ Reference

    公有成员函数 std::list::remove void remove(const value_type& val); 删除与给定值相等的元素 从容器中删除所有与 val 值相等的元素.li ...

  8. Python 技术点

    1.文件操作 1-1 遍历文件夹和文件 import os rootDir = "/path/to/root" for parent, dirnames, filenames in ...

  9. 08:Python数据分析之pandas学习

    1.1 数据结构介绍 参考博客:http://www.cnblogs.com/nxld/p/6058591.html 1.pandas介绍 1. 在pandas中有两类非常重要的数据结构,即序列Ser ...

  10. exp9《网络对抗》web安全基础实践201453331魏澍琛

    201453331魏澍琛web安全基础实践 一.实验过程 1.webgoat开启 2.Injection Flaws练习 Command Injection 原网页中没有注入的地方,那就用burpsu ...