C# 代理/委托 Delegate
委托是函数的封装,它代表一"类"函数.
他们都符合一定的签名:拥有相同的参数列表,返回值类型.同时,委托也可以看成是对函数的抽象,是函数的"类".此时,委托的实例将代表一个具体的函数.
委托声明和定义了一个引用类型,它用来封装方法,用指定的签名来封装方法.一个委托的实例,可以封装静态或者实例方法.
委托是一种引用的类型,一旦为委托分配了方法,委托将与该方法完全相同的行为,委托方法的使用可以像其他任何方法一样, 具有参数和返回值
委托的一个特征是它们的类型是安全的.可以确保被调用的方法签名是正确的,但他们并不关心调用该方法的是什么类型的对象,甚至不考虑该方法是静态方法还是实例方法.(给定委托的实例可以表示任何类型的任何对象上的实例方法或静态方法,只要方法的签名匹配于委托的签名就可以).
2. 委托的使用:
当要把方法传递给其他方法时,需要使用委托.
为什么什么用委托:
更加灵活的方法调用.
用于异步回调.
多线程编程中使用委托来定启动一个线程时调用的方法.
C#中的事件模型,用他们来指明处理给定事件的方法.
例:
class Program
{
//定义委托
delegate double ProcessDelegate(double param1, double param2);
static double Multiply(double param1, double param2)
{
return param1 * param2;
}
static double Divide(double param1, double param2)
{
return param1 / param2;
}
static void Main(string[] args)
{
//定义委托变量
ProcessDelegate pd;
double param1 = 20;
double param2 = 10;
Console.WriteLine("Enter M to multiply or D to divide");
string input = Console.ReadLine();
if (input == "M")
{
//初始化委托变量,要把一个函数引用赋给委托变量,
//参数是要使用的函数名,且不带括号.
pd = new ProcessDelegate(Multiply);
}
else
{
pd = new ProcessDelegate(Divide);
}
//使用该委托调用所选函数
Console.WriteLine("Result: {0}",pd(param1,param2));
Console.ReadKey();
}
3. 多播委托: 引用多个方法的委托,它连续调用每个方法.
为了把委托的单个实例合并为一个多播委托,委托必须是同类型的,返回类型必须是void,不能带输出参数out(可以带引用参数ref).
多播委托应用于事件模型中.
//声明委托
public delegate void myDelegate();
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
public void aa()
{
Console.WriteLine("aa");
}
public void bb()
{
Console.WriteLine("bb");
}
public void cc()
{
Console.WriteLine("cc");
}
myDelegate md;
private void button1_Click(object sender, EventArgs e)
{
md = new myDelegate(aa);
md += new myDelegate(bb);
myDelegate m = new myDelegate(cc);
md += m ;
md();
}
}
4. 异步回调:
由于实例化委托是一个对象,所以可以将其作为参数进行传递.也可以将其赋值给属性.这样,方法便可以将一个委托作为参数来接受,并且以后可以调用该委托.这样称为异步回调,是在较长的进程完成后用来通知调用方的常用方法.以这种方式使用委托时,使用委托的代码无需了解有关所用方法的实现方面的任何信息.
回调的另一个常见用法是定义自定义的比较方法并将该委托传递给排序方法.
例:
//定义委托
delegate void Del(int a,int b);
class Program
{
static void Main(string[] args)
{
Program p = new Program();
Del d = new Del(p.F_min); //实例化委托并传给他比较的方法.
p.CallBack(10, 30, d); //调用回调函数
}
//回调函数,将委托实例作为方法参数进行传递.
public void CallBack(int a,int b,Del d)
{
d(a, b); //执行委托
}
//输出较大的数
public void F_max(int a, int b)
{
Console.WriteLine("大的那个数为: " + Math.Max(a,b));
}
//输出较小的数
}
5. 匿名方法
匿名方法允许我们以一种”内联”的方式来编写方法代码,将代码直接与委托实例相关联,从而使得委托实例化的工作更加直观和方便.
使用例子:
class Program{
//定义委托
public delegate string dTest(string val);
static void Main(string[] args){
string mid = "男子足球队";
//匿名方法
dTest aDelegate = delegate(string param){
param += mid;
param += "加油.";
return param;
};
Console.WriteLine(aDelegate("中国"));
Console.ReadLine();
}
}
如果委托类型的返回类型为void,匿名方法里便不能返回任何值.如果不为void,匿名方法里返回的值必须和委托类型的返回值兼容.
6. 何时使用委托,何时接口?
委托:
当使用事件设计模式时.
当封装静态方法可取时.
当调用方不需要访问实现该方法的对象中的其他属性方法或接口时.
需要方便的组合.
当类可能需要该方法的多个实现时.
接口:
当存在一组可能被调用的相关方法时.
当类只需要方法的单个实现时.
当使用接口的类想要将该接口强制转换为其他接口或类类型时.
public void F_min(int a, int b)
{
Console.WriteLine("小的那个数为: " +Math.Min(a,b));
}
C# 代理/委托 Delegate的更多相关文章
- 【C#】事件(Event)和代理/委托(Delegate)
代理(Delegate)的例子 delegate void MyDelegate(string str,int index); // 声明代理 class Test { public static v ...
- [.NET] C# 知识回顾 - 委托 delegate (续)
C# 知识回顾 - 委托 delegate (续) [博主]反骨仔 [原文]http://www.cnblogs.com/liqingwen/p/6046171.html 序 上篇<C# 知识回 ...
- [C#] C# 知识回顾 - 委托 delegate
C# 知识回顾 - 委托 delegate [博主]反骨仔 [原文]http://www.cnblogs.com/liqingwen/p/6031892.html 目录 What's 委托 委托的属性 ...
- C# 委托Delegate(一) 基础介绍&用法
本文是根据书本&网络 前人总结的. 1. 前言 定义&介绍: 委托Delegate是一个类,定义了方法的类型, 使得可以将方法当做另一个方法的参数来进行传递,这种将方法动态地赋给参数的 ...
- UIScrollView的代理(delegate)
很多时候,我们想在UIScrollView正在滚动 或 滚动到某个位置 或者 停止滚动 时做一些特定的操作 要想完成上述功能,前提条件就是能够监听到UIScrollView的整个滚动过程 当UIScr ...
- UIScrollView无法滚动的解决办法及UIScrollView的代理(delegate)
1•如果UIScrollView无法滚动,可能是以下原因: Ø没有设置contentSize ØscrollEnabled = NO Ø没有接收到触摸事件:userInteractionEnabled ...
- 为什么不能把委托(delegate)放在一个接口(interface)当中?
stackoverflow上有人问,为什么不能把委托放在一个接口当中? 投票最多的第一个答案第一句话说,“A Delegate is just another type, so you don't g ...
- c# 委托 delegate
委托是一种存储函数引用的类型,在事件和事件的处理时有重要的用途 通俗的说,委托是一个可以引用方法的类型,当创建一个委托,也就创建一个引用方法的变量,进而就可以调用那个方法,即委托可以调用它所指的方法. ...
- 理解委托(delegate)及为什么要使用委托
理解委托(delegate)及为什么要使用委托 委托:是一种定义方法签名的类型. 当实例化委托时,您可以将其实例与任何具有兼容签名的方法相关联. 您可以通过委托实例调用方法. 上述为官方说法,理解起来 ...
随机推荐
- log4j:WARN Please initialize the log4j system properly.解决
log4j:WARN No appenders could be found for logger (org.springframework.context.support.ClassPathXmlA ...
- poj3692 最大点权独立集/最大独立集
题意:有男孩和女孩,男孩之间全部认识,女孩之间全部认识,一部分男孩和女孩认识,现在希望选出一些孩子,这些孩子都相互认识. 方法:正的做不好做,观察他的补图,补图之间无关系的边就是原图有关系的.补图中的 ...
- SSH配置文件和SSM配置文件的写法
一.SSH配置文件的写法(XML版本) <util:properties id="jdbc" location="classpath:db.properties&q ...
- POJ1037A decorative fence(动态规划+排序计数+好题)
http://poj.org/problem?id=1037 题意:输入木棒的个数n,其中每个木棒长度等于对应的编号,把木棒按照波浪形排序,然后输出第c个; 分析:总数为i跟木棒中第k短的木棒 就等于 ...
- php绝对路径与相对路径之间关系的的深入研究
php中好像不能像asp那样用“/”表示根目录,代之以$_SERVER['DOCUMENT_ROOT'],其它则相同:../表示向上一层../表示当前层.假如现在a/b/c/s.php要调用根目录下的 ...
- Java初学(二)
一.数据类型 在定义Long或者Float类型变量的时候,要加L或f(大小写无关,只是便于识别,建议不要小写L) 整数默认是int,浮点数默认是double 二.java字符 java语言采用的是Un ...
- jQuery插件开发教程
jQuery插件开发教程 ——让你的jQuery水平提升一个台阶 要说jQuery 最成功的地方,我认为是它的可扩展性吸引了众多开发者为其开发插件,从而建立起了一个生态系统.这好比大公司们争相做平台 ...
- 基础知识系列☞Abstract和Virtual→及相关知识
转载地址→http://www.cnblogs.com/blsong/archive/2010/08/12/1798064.html 在C#的学习中,容易混淆virtual方法和abstract方法的 ...
- 八大常见内排序java实现
虽然排序算法烂大街了,但是哥依然用java实现了一遍,只为自己练练手,后面可以时不时的回头看看...仅此而已,各位可以提意见,莫喷!! 一.冒泡排序 基本思想:在要排序的一组数中,对当前还未排好序的范 ...
- mapreduce job提交流程源码级分析(一)(原创)
首先,在自己写的MR程序中通过org.apache.hadoop.mapreduce.Job来创建Job.配置好之后通过waitForCompletion方法来提交Job并打印MR执行过程的log.H ...