• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号
您的位置:首页 > 程序设计 >C#教程 > 深入理解C#中的Delegate

深入理解C#中的Delegate

作者:ShirlySaku 字体:[增加 减小] 来源:互联网 时间:2017-05-28

ShirlySaku 通过本文主要向大家介绍了深入理解c#第3版pdf,clr via c,深入理解c# mobi,c#图解教程,c#高级编程等相关知识,希望对您有所帮助,也希望大家支持linkedu.com www.linkedu.com

在c#中,event与delegate是两个非常重要的概念。因为在Windows应用程序中,对事件的使用非常频繁,而事件的实现依赖于delegate。

下面是对网上一些比较好的关于delegage的资料的整理,以及自己的一些想法。

Delegate是什么?

   Delegate中文翻译为“委托”。Msdn中对Delegate的解释如下:

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

一旦为委托分配了方法,委托将与该方法具有完全相同的行为。委托方法的使用可以像其他任何方法一样,具有参数和返回值,如下面的示例所示:

public delegate void Del(string message);
</div>

与委托的签名(由返回类型和参数组成)匹配的任何方法都可以分配给该委托。这样就可以通过编程方式来更改方法调用,还可以向现有类中插入新代码。只要知道委托的签名,便可以分配自己的委托方法。

调用委托

构造委托对象时,通常提供委托将包装的方法的名称或使用匿名方法。实例化委托后,委托将把对它进行的方法调用传递给方法。调用方传递给委托的参数被传递给方法,来自方法的返回值(如果有)由委托返回给调用方。这被称为调用委托。可以将一个实例化的委托视为被包装的方法本身来调用该委托。例如:

// Create a method for a delegate.
public static void DelegateMethod(string message)
{
System.Console.WriteLine(message);
}
// Instantiate the delegate.
Del handler = DelegateMethod;
// Call the delegate.
handler("Hello World");
</div>

将委托构造为包装实例方法时,该委托将同时引用实例和方法。除了它所包装的方法外,委托不了解实例类型,所以只要任意类型的对象中具有与委托签名相匹配的方法,委托就可以引用该对象。将委托构造为包装静态方法时,它只引用方法。

回调

由于实例化委托是一个对象,所以可以将其作为参数进行传递,也可以将其赋值给属性。这样,方法便可以将一个委托作为参数来接受,并且以后可以调用该委托。这称为异步回调,是在较长的进程完成后用来通知调用方的常用方法。以这种方式使用委托时,使用委托的代码无需了解有关所用方法的实现方面的任何信息。此功能类似于接口所提供的封装。

回调的另一个常见用法是定义自定义的比较方法并将该委托传递给排序方法。它允许调用方的代码成为排序算法的一部分。下面的示例方法使用 Del 类型作为参数:

public void MethodWithCallback(int param1, int param2, Del callback)
{
callback("The number is: " + (param1 + param2).ToString());
}
</div>

然后可以将上面创建的委托传递给该方法:

MethodWithCallback(1, 2, handler);
</div>

在控制台中将收到下面的输出:

The number is: 3

使用委托的好处

委托允许类设计器分离类型声明和实现。

在将委托用作抽象概念时,MethodWithCallback 不需要直接调用控制台 -- 设计它时无需考虑控制台。MethodWithCallback 的作用只是准备字符串并将该字符串传递给其他方法。此功能特别强大,因为委托的方法可以使用任意数量的参数。

将方法作为参数进行引用的能力使委托成为定义回调方法的理想选择。例如,可以向排序算法传递对比较两个对象的方法的引用。分离比较代码使得可以采用更通用的方式编写算法。

如何使用委托

1. 声明委托

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

2. 实例化委托

声明了委托类型后,必须创建委托对象并使之与特定方法关联。方法的签名应与委托定义的签名一致。

委托对象可以关联静态方法,也可以关联非静态方法。

委托一旦创建,它的关联方法就不能更改;委托对象是不可变的。

3. 调用委托

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

下面是一个示例:

using System;
public class SamplesDelegate
{
// Declares a delegate for a method that takes in an int and returns a String.
public delegate String myMethodDelegate(int myInt);
// Defines some methods to which the delegate can point.
public class mySampleClass
{
// Defines an instance method.
public String myStringMethod(int myInt)
{
if (myInt > 0)
return ("positive");
if (myInt < 0)
return ("negative");
return ("zero");
}
// Defines a static method.
public static String mySignMethod(int myInt)
{
if (myInt > 0)
return ("+");
if (myInt < 0)
return ("-");
return ("");
}
}
public static void Main()
{
// Creates one delegate for each method.
mySampleClass mySC = new mySampleClass();
myMethodDelegate myD1 = new myMethodDelegate(mySC.myStringMethod);
myMethodDelegate myD2 = new myMethodDelegate(mySampleClass.mySignMethod);
// Invokes the delegates.
Console.WriteLine("{0} is {1}; use the sign /"{2}/".", 5, myD1(5), myD2(5));
Console.WriteLine("{0} is {1}; use the sign /"{2}/".", -3, myD1(-3), myD2(-3));
Console.WriteLine("{0} is {1}; use the sign /"{2}/".", 0, myD1(0), myD2(0));
}
}
/*
This code produces the following output:
5 is positive; use the sign "+".
-3 is negative; use the sign "-".
0 is zero; use the sign "".
*/
</div>

多路广播

调用委托时,它可以调用多个方法。这称为多路广播。若要向委托的方法列表(调用列表)中添加额外的方法,只需使用加法运算符或加法赋值运算符(“+”或“+=”)添加两个委托。例如:

MethodClass obj = new MethodClass();
Del d1 = obj.Method1;
Del d2 = obj.Method2;
Del d3 = DelegateMethod;
//Both types of assignment are valid.
Del allMethodsDelegate = d1 + d2;
allMethodsDelegate += d3;
</div>

此时,allMethodsDelegate 在其调用列表中包含三个方法 -- Method1、Method2 和 DelegateMethod。原来的三个委托 d1、d2 和 d3 保持不变。调用 allMethodsDelegate 时,将按顺序调用所有这三个方法。如果委托使用引用参数,则引用将依次传递给三个方法中的每个方法,由一个方法引起的更改对下一个方法是可见的。如果任一方法引发了异常,而在该方法内未捕获该异常,则该异常将传递给委托的调用方,并且不再对调用列表中后面的方法进行调用。如果委托具有返回值和/或输出参数,它将返回最后调用的方法的返回值和参数。若要从调用列表中移除方法,请使用减法运算符或减法赋值运算符(“-”或“-=”)。例如:

//remove Method1
allMethodsDelegate -= d1;
// copy AllMethodsDelegate while removing d2
Del oneMethodDelegate = allMethodsDelegate - d2;
</div>

多路广播委托广泛用于事件处理中。事件源对象向已注册接收该事件的接收方对象发送事件通知。为了为事件注册,接收方创建了旨在处理事件的方法,然后为该方法创建委托并将该委托传递给事件源。事件发生时,源将调用委托。然后,委托调用接收方的事件处理方法并传送事件数据。给定事件的委托类型由事件源定义。
本示例演示如何组合多路广播委托。委托对象的一个用途在于,可以使用 + 运算符将它们分配给一个要成为多路广播委托的委托实例。组合的委托可调用组成它的那两个委托。只有相同类型的委托才可以组合。

运算符可用来从组合的委托移除组件委托。

delegate void Del(string s); 
class TestClass
{
static void Hello(string s)
{
System.Console.WriteLine(" Hello, {0}!", s);
}
static void Goodbye(string s)
{
System.Console.WriteLine(" Goodbye, {0}!", s);
}
static void Main()
{
Del a, b, c, d;
// Create the delegate object a that references
// the method Hello:
a = Hello;
// Create the delegate object b that references
// the method Goodbye:
b



 
分享到:QQ空间新浪微博腾讯微博微信百度贴吧QQ好友复制网址打印

您可能想查找下面的文章:

  • 深入理解C♯ 7.0中的Tuple特性
  • 深入理解C# DateTime日期格式化
  • 深入理解C#的数组
  • 深入理解C#中的Delegate
  • 深入理解C#中new、override、virtual关键字的区别
  • 深入理解C#中常见的委托

相关文章

  • 2017-05-28C#值类型和引用类型的深入理解
  • 2017-05-28C#使用linq计算执行元素在列表中出现次数的方法
  • 2017-05-28c# winform读取xml文件创建菜单的代码
  • 2017-05-28C#调用系统API指定快捷键的方法
  • 2017-05-28C# NetRemoting实现双向通信
  • 2017-05-28C#实现的json序列化和反序列化代码实例
  • 2017-05-28C#将图片存放到SQL SERVER数据库中的方法
  • 2017-05-28C#七大经典排序算法系列(上)
  • 2017-05-28C#遍历子目录的方法
  • 2017-05-28C#中的yield关键字的使用方法介绍

文章分类

  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号

最近更新的内容

    • C#递归算法之分而治之策略
    • C#如何防止程序多次运行的技巧
    • 微信公众平台开发教程(三) 基础框架搭建
    • 使用C#给PDF文档添加注释的实现代码
    • c# 递归访问文件夹(删掉歌词文件)
    • treeview递归绑定的两种方法
    • c#操作xml帮助类分享(xml增删改查)
    • C#中DataTable导出为HTML格式的方法
    • 解析C#设计模式编程中适配器模式的实现
    • WPF中的ListBox实现按块显示元素的方法

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有