C#中委托如何使用?(转帖)
1.委托概述
委托是C#中新加入的一个类型,可以把它想作一个和Class类似的一种类型,和使用类相似,使用一个委托时,需要两个步骤,首先你要定义一个委托,就像是定义一个类一样;然后,你可以创建一个或多个该委托的实例。
定义一个委托的语法是这样的:
[public/protected/private] delegate returnType delegateName(paramtype param1,…)
这是我自己写的,看起来好像有点怪怪的,我来解释一下,private/protected/private是限定词,就不多说了,delegate是申明一个委托的关键词,returnType是一个返回类型,delegateName是一个你给委托起的名字,你可以写任何一个你喜欢的名字,paramtype param1…这个是参数列表。说了这么多可能看起来还是不是很好理解,我是这样认为的,实用点来讲,委托定义就是在一个函数定义中间加入一个delegate的关键词。它的作用类似于你申明一个类:
public class ClassName {…}
创建一个委托的实例:
[public/protected/private] delegateName deleInstanceName = new delegateName(MethodName)
这个类似于实例化一个类,public ClassName instancename = new ClassName(…),这里有个要注意的地方,即MethodName方法要和delegateName的签名一致。什么是签名一致,就是说MethodName的参数列表,返回值要分别和returnType、(paramtype param1,…)一致。举个例子来说明下:
public delegate string DelegateDemo(string name, int age);
比如我们如上定义了一个委托,就写法来说,其实就是在函数 string DelegateDemo(string name, int age)前面加了一个delegate的关键字,下面我们来用创建一个函数:
public string AgentDemo(string name, int age)
{
string rev = “”;
…
return rev;
}
这个函数是做参数传递给一个DelegateDemo实例的,接下来创建一个DelegateDemo的实例:
DelegateName instanceDemo = new DelegateName(AgentDemo);
这时要说到一致了,即AgentDemo和声明委托时的DelegateDemo(我们姑且将delegate去掉)这两个函数的返回值,参数列表要相同。终于说完了,不知道看的人明不明白。
接下来,我们可以使用这个委托了(调用一个委托),如下:
string name = “cshape”;
int age = 20;
instanceDemo(name, age);
当instanceDemo执行时,会执行AgentDemo函数,instanceDemo相当于C里的一个函数指针,现在这个指针指向AgentDemo的函数入口地址。
2.多点委托
前面提到的委托都只包含对一个方法的调用,如果需要调用多个方法,需要多次显示的调用这个委托,我们还有另的选择,我们可以让一个委托中包含多个方法,这样我们一次显示调用委托,就可以按照顺序连续的调用多个方法。看下面的例子:
public delegate void MultiDelegate(string name);
public void AgentDemo1(string str)
{
Console.WriteLine(str + “this is AgentDemo1\n”);
}
public void AgentDemo2(string s)
{
Console.WriteLine(s + “this is AgentDemo2\n”);
}
MultiDelegate multiDemo = new MultiDelegate(AgentDemo1);
multiDemo += new MultiDelegate(AgentDemo2);
multiDemo(“multiDemo test :”);
输出的结果应该是:
multiDemo test :this is AgentDemo1
mutliDemo test :this is AgentDemo2
可以看到我们一次显示的调用一个委托,它顺序的(按照你添加方法的顺序)执行了方法AgentDemo1和AgentDemo2。这里要注意的有几点:
● 委托支持 +=,-=这样的运算符,对应为添加或去掉一个方法
● 多点委托不可以定义有返回值,因为无法处理多个方法的返回值,所以如果要使用多点委托,应该用void,否则你的编译会返回一个错误
● 多点委托不建议你的参数列表中有OUT的类型,这样只会out最后一个方法的值,其他的值会丢失。
3.委托的理解
首先申明,这只是我举的一个例子,目的是帮助理解委托的过程,其中很多地方都经不起推敲,望大家知悉。言归正传,
你想要吃饭,
但是自己又不会做(委托方不知道实现细节),
你计划找个饭店,叫个回锅肉饭(定义了一个委托)
你决定找常去的那家叫做A的饭店(实例化一个委托)
你打电话给A饭店(委托调用)
A饭店给你做好了你的回锅肉饭(代理函数工作)
饭来了,真好。
4.委托的使用时机
当你需要把一个方法传送给其他方法时,可以考虑使用委托。好像不是很好理解,也可以这样说,当你确定要处理一件事,但又不能确定处理方法时,可以考虑用委托。其实单独的说委托的应用好像有点牵强,委托更多的是在事件中的应用。
5.一个委托的例子
我用两个类来做这个例子,一个类,我称它为委托方,一个类我称它为代理方,代码如下:
using System;
namespace Visen.Demo.Delegate
{
///<summary>
/// StartUp 委托演示中的程序入口,含委托方。
///</summary>
class StartUp
{
#region公用的方法
#region应用程序的主入口点。
///<summary>
///应用程序的主入口点。
///</summary>
[STAThread]
static void Main(string[] args)
{
Console.WriteLine("This is a delegate demo\n");
Visen.Demo.Delegate.Agent ag = new Agent();
//定义一个委托类型的对象
OutMessage singleDele = new OutMessage(ag.ShowMessage);
OutMessage deleStaticMeth = new OutMessage(Agent.SShowMessage);
//定义一个多点委托
OutMessage MultiDele = new OutMessage(ag.ShowMessage);
MultiDele += new OutMessage(Agent.SShowMessage);
singleDele(" delegate instance singleDele");
deleStaticMeth(" delegate instance deleStaticMeth");
MultiDele(" this is a MultiDele");
Console.Read();
}
#endregion应用程序的主入口点。
#endregion公用的方法
#region私用的字段
///<summary>
///定义一个委托类型
///</summary>
private delegate void OutMessage(string msg);
#endregion私有的字段
}
}
下面是代理方:
using System;
namespace Visen.Demo.Delegate
{
///<summary>
/// Agent 类为委托者的代理方,处理委托者委托的事务。
///</summary>
public class Agent
{
#region公用的方法
#region空的构造函数
///<summary>
///空的构造函数
///</summary>
public Agent()
{
}
#endregion空的构造函数
#region显示一条信息到控制台,一个类成员函数作为代理方
///<summary>
///显示一条信息到控制台,一个类成员函数作为代理方
///</summary>
///<param name="msg">显示内容</param>
public void ShowMessage(string msg)
{
Console.WriteLine("Method ShowMessage out:" + msg + "\n");
}
#endregion显示一条信息到控制台,一个类成员函数作为代理方
#region显示一条信息到控制台,一个类静态函数作为代理方
///<summary>
///显示一条信息到控制台,一个类静态函数作为代理方
///</summary>
///<param name="msg">显示信息</param>
public static void SShowMessage(string msg)
{
Console.WriteLine("static Method SShowMessage out:" + msg + "\n");
}
#endregion显示一条信息到控制台,一个类静态函数作为代理方
#endregion公用的方法
}
}
输出为:
This is a delegate demo
Method ShowMessage out: delegate instance singleDele
static Method SShowMessage out: delegate instance deleStaticMeth
Method ShowMessage out: this is a MultiDele
static Method SShowMessage out: this is a MultiDele
可见:方法函数可以是类成员函数,也可以是一个静态成员,只要和委托的签名相同就可以了。
C#中委托如何使用?(转帖)的更多相关文章
- C#中委托和事件的区别实例解析
这篇文章主要介绍了C#中委托和事件的区别,并分别以实例形式展示了通过委托执行方法与通过事件执行方法,以及相关的执行流程与原理分析,需要的朋友可以参考下 本文实例分析了C#中委托和事件的区别,分享给大家 ...
- C#中委托和事件
目 录 将方法作为方法的参数 将方法绑定到委托 更好的封装性 限制类型能力 范例说明 Observer 设计模式简介 实现范例的Observer 设计模式 .NET 框架中的委托与事件 为什么委托定义 ...
- 详解Objective-C中委托和协议
Objective-C委托和协议本没有任何关系,协议如前所述,就是起到C++中纯虚类的作用,对于“委托”则和协议没有关系,只是我们经常利用协议还实现委托的机制,其实不用协议也完全可以实现委托. AD: ...
- C# 在word文档中复制表格并粘帖到下一页中
C# 在word文档中复制表格并粘帖到下一页中 object oMissing = System.Reflection.Missing.Value; Microsoft.Offi ...
- c#中委托和事件(转)
C# 中的委托和事件 引言 委托 和 事件在 .Net Framework中的应用非常广泛,然而,较好地理解委托和事件对很多接触C#时间不长的人来说并不容易.它们就像是一道槛儿,过了这个槛的人,觉得真 ...
- C#中委托
委托是一种安全地封装方法的类型,它与 C 和 C++ 中的函数指针类似.与 C 中的函数指针不同,委托是面向对象的.类型安全的和保险的.一个委托类型是代表与特定参数列表和返回类型的方法的引用类型.实例 ...
- C#中委托的理解
请注意,这只是个人关于C#中委托的一点点理解,参考了一些博客,如有不周之处,请指出,谢谢! 委托是一种函数指针,委托是方法的抽象,方法是委托的实例.委托是C#语言的一道坎,明白了委托才能算是C#真正入 ...
- C#中委托的发展与匿名函数
匿名函数(C# 编程指南) 匿名函数是一个“内联”语句或表达式,可在需要委托类型的任何地方使用. 可以使用匿名函数来初始化命名委托,或传递命名委托(而不是命名委托类型)作为方法参数. 共有两种匿名函数 ...
- C#不用union,而是有更好的方式实现 .net自定义错误页面实现 .net自定义错误页面实现升级篇 .net捕捉全局未处理异常的3种方式 一款很不错的FLASH时种插件 关于c#中委托使用小结 WEB网站常见受攻击方式及解决办法 判断URL是否存在 提升高并发量服务器性能解决思路
C#不用union,而是有更好的方式实现 用过C/C++的人都知道有个union,特别好用,似乎char数组到short,int,float等的转换无所不能,也确实是能,并且用起来十分方便.那C# ...
随机推荐
- XML文档的创建
右键项目,添加,新建项,XML文件 XML文件的第一行有一个标题,标题描述了这个XML文件的版本和编码 XML文件必须有根节点且只能有一个根节点,如<Books></Books> ...
- Animation鱼眼效果
<!DOCTYPE html><html xmlns="http://www.w3.org/1999/xhtml"><head> < ...
- 使用pthread_create()创建线程
可以通过 pthread_create()函数创建新线程. #include <pthread.h> int pthread_create(pthread_t *restrict tidp ...
- java并发编程:线程安全管理类--原子操作类--AtomicMarkableReference<V>
1.类 AtomicMarkableReference<V> public class AtomicMarkableReference<V>extends Object Ato ...
- BZOJ1197 [HNOI2006]花仙子的魔法
其实是一道奇怪的DP题,蒟蒻又不会做... 看了Vfk的题解才算弄明白是怎么一回事: 令f[i, j]表示i维有j个球时最大切割部分,则 f[i, j] = f[i, j - 1] + f[i - 1 ...
- 蓝桥杯—ALGO-18 单词接龙(DFS)
问题描述 单词接龙是一个与我们经常玩的成语接龙相类似的游戏,现在我们已知一组单词,且给定一个开头的字母, 要求出以这个字母开头的最长的“龙”(每个单词都最多在“龙”中出现两次) ,在两个单词相连时,其 ...
- simulate mdns message
use dns-sd command simulate mdns message: dns-sd -R test _test._tcp local 1234 a=1111111111111111111 ...
- 使用简单的python语句编写爬虫 定时拿取信息并存入txt
# -*- coding: utf-8 -*- #解决编码问题import urllibimport urllib2import reimport osimport time page = 1url ...
- Linux内核分析-Linux内核如何装载和启动一个可执行程序
ID:fuchen1994 实验要求: 理解编译链接的过程和ELF可执行文件格式,详细内容参考本周第一节: 编程使用exec*库函数加载一个可执行文件,动态链接分为可执行程序装载时动态链接和运行时动态 ...
- 做了一个vue的同步tree 的npm组件包
前言:因为现成的tree组件没有找到.亦或是其依赖的其他东西太多,不太合适引入我们的项目,所以自己做了一个.大概样式: 在线例子: https://hamupp.github.io/t-vue-tre ...