Delegate,Action,Func,匿名方法,匿名委托,事件 (转载)
Delegate,Action,Func,匿名方法,匿名委托,事件 (转载)
一、委托Delegate
一般的方法(Method)中,我们的参数总是string,int,DateTime...这些基本的数据类型(或者没有参数),比如
publicvoid HelloWorld()
{
Console.WriteLine("Hello World!");
}
publicvoid HelloWorld(string name)
{
Console.WriteLine("Hello ,{0}!", name);
}
但是有些时候,我们希望把一个方法本身当做参数传递给另一个方法,比如
myObject.callMethod(HelloWorld);
在没有委托之前,这是一件极困难的事情,委托出现以后,这就是一件很容易的事情了,简单点讲:委托就是一种能把方法当做参数来使用的类型--当然这个定义跟官方的解释比起来极不严密,但易于理解
要点:
1.委托是一种类型(跟string,int,double...一样是.net的一种基本类型)
2.委托的定义必须与最终被调用的方法保持签名一致
比如:下面代码中的
delegate void D1(); 与 static void HelloWorld1(),我们抛开前面的类型关键字delegate与static,他们的签名都是void X()
void D2(string myName);与void HelloWorld2(string name); void HelloWorld3(string name);它们的签名格式都是 void X(string Y)
3.委托的好处之一在于可以保持签名格式不变的情况下,动态调用不同的处理逻辑(即不同的方法)
想想系统控件中的Button类,系统并不知道按钮按下去时到底会执行怎么样的逻辑(点击后的处理,每个项目可能都不一样,完全由需求决定),但是我们知道每个Button都有一个Click(object sender, EventArgs e)这样的东东,没错,就是委托(当然封装成了另一种衍生类型event),就是这种设计保证了统一的格式,不管你实际开发中想如何处理点击后的逻辑,只要按这个统一的签名来就行了
完整代码演示:
using System;
namespace ActionStudy
{
class Program
{
delegatevoid D1();
delegatevoid D2(string myName);
staticvoid Main(string[] args)
{
D1 d1 =new D1(HelloWorld1);
d1();
D2 d2 =new D2(HelloWorld2);
d2("Jimmy");
d2 =new D2(HelloWorld3);
d2("杨俊明");
Console.Read();
}
staticvoid HelloWorld1()
{
Console.WriteLine("Hello World!");
}
staticvoid HelloWorld2(string name)
{
Console.WriteLine("Hello,{0}!", name);
}
staticvoid HelloWorld3(string name)
{
Console.WriteLine("你好,{0}!", name);
}
}
}
二 、匿名方法(.net2.0开始支持)
在“一、委托Delegate”的演示代码中,我们看到委托调用方法前,至少得先定义一个签名相同的方法,然后才能由委托调用(哪怕是只有一行代码的方法),好象有点烦哦,想偷懒,ok,没问题
using System;
namespace ActionStudy
{
class Program
{
delegatevoid D1();
delegatevoid D2(string myName);
staticvoid Main(string[] args)
{
D1 d1 =delegate
{
Console.WriteLine("Hello World!");
};
d1();
D2 d2 =delegate(string name)
{
Console.WriteLine("Hello,{0}!", name);
};
d2("Jimmy");
d2 =delegate(string name)
{
Console.WriteLine("你好,{0}!", name);
};
d2("杨俊明");
Console.Read();
}
}
}
运行效果完全相同,只是省去了方法的单独定义部分
到了.net 3.0这种偷懒的作风更夸张,看下面的代码(利用了Lambda表达式)
using System;
namespace ActionStudy
{
class Program
{
delegatevoid D1();
delegatevoid D2(string myName);
staticvoid Main(string[] args)
{
D1 d1 = () => { Console.WriteLine("Hello World!"); };
d1();
D2 d2 = (string name) => { Console.WriteLine("Hello,{0}!", name); };
d2("Jimmy");
d2 = (string name) => { Console.WriteLine("你好,{0}!", name); };
d2("杨俊明");
Console.Read();
}
}
}
运行效果仍然没变,初次接触者可能感觉很怪,其实我也觉得怪,不过很多大牛们都喜欢这样用,所以至少还是要能看得懂,否则别人会说"你 Out了" :)
三、Action
Action的本质就是委托,看它的定义:
namespace System
{
// 摘要:
// Encapsulates a method that takes no parameters and does not return a value.
publicdelegatevoid Action();
}
namespace System
{
// 摘要:
// Encapsulates a method that takes a single parameter and does not return a
// value.
//
// 参数:
// obj:
// The parameter of the method that this delegate encapsulates.
//
// 类型参数:
// T:
// The type of the parameter of the method that this delegate encapsulates.
publicdelegatevoid Action<T>(T obj);
}
当然,还有Action<T1,T2>乃至Action<T1,T2,T3,T4>参数个数从2到4的类型,不过定义都差不多
简单点讲,Action是参数从0到4,返回类型为void(即没有返回值)的委托
using System;
namespace ActionStudy
{
class Program
{
static Action A1;
static Action<string> A2;
staticvoid Main(string[] args)
{
A1 =new Action(HelloWorld1);
A1();
A2 =new Action<string>(HelloWorld2);
A2("Jimmy");
A2 = (string name) => { Console.WriteLine("你好,{0}!", name); };
A2("杨俊明");
A2 =delegate(string name) { Console.WriteLine("我就是委托,{0} 你说对吗?", name); };
A2("菩提树下的杨过");
Console.Read();
}
staticvoid HelloWorld1()
{
Console.WriteLine("Hello World!");
}
staticvoid HelloWorld2(string name)
{
Console.WriteLine("Hello,{0}!", name);
}
}
}
四、Func
Func其实也是一个"托"儿,呵呵,不过这个委托是有返回值的。看下定义就知道了:
namespace System
{
// 摘要:
// Encapsulates a method that has no parameters and returns a value of the type
// specified by the TResult parameter.
//
// 类型参数:
// TResult:
// The type of the return value of the method that this delegate encapsulates.
//
// 返回结果:
// The return value of the method that this delegate encapsulates.
publicdelegate TResult Func<TResult>();
}
namespace System
{
// 摘要:
// Encapsulates a method that has one parameter and returns a value of the type
// specified by the TResult parameter.
//
// 参数:
// arg:
// The parameter of the method that this delegate encapsulates.
//
// 类型参数:
// T:
// The type of the parameter of the method that this delegate encapsulates.
//
// TResult:
// The type of the return value of the method that this delegate encapsulates.
//
// 返回结果:
// The return value of the method that this delegate encapsulates.
publicdelegate TResult Func<T, TResult>(T arg);
}
同Action类似,Func的参数从1到5个,有5个不同的重载版本
代码:
using System;
namespace ActionStudy
{
class Program
{
static Func<string> F;
static Func<DateTime, string> F2;
staticvoid Main(string[] args)
{
F =new Func<string>(HelloWorld1);
Console.WriteLine(F());
F2 =new Func<DateTime, string>(HelloWorld2);
Console.WriteLine(F2(DateTime.Now));
Console.Read();
}
staticstring HelloWorld1()
{
return"Hello World!";
}
staticstring HelloWorld2(DateTime time)
{
returnstring.Format("Hello World,the time is {0}.", time);
}
}
}
五、匿名委托
ok,如果你没有晕的话,再来看一下匿名委托,其实这也是一种偷懒的小伎俩而已
看代码说话:
//F = new Func<string>(HelloWorld1);
其实也可以简写成这样:
F = HelloWorld1;
//F2 = new Func<DateTime, string>(HelloWorld2);
其实也可以简写成这样
F2 = HelloWorld2;
方法直接赋值给委托,这二个类型不同吧???
没错,你会发现编译一样能通过,系统在编译时在背后自动帮我们加上了类似 “= new Func<...>”的东东,所以我们能偷懒一下下,这个就是匿名委托。
如果你细心的话,会发现我们在定义Button的Click处理事件时,通常是这样的:
this.button1.Click += new EventHandler(button1_Click);
但有时候我们也可以写成这样:
this.button1.Click += button1_Click;
这其实就是匿名委托的应用.
六、事件event
其实,这...还是个托儿!
我们来看下按钮Click事件的定义
// 摘要:
// Occurs when the control is clicked.
publicevent EventHandler Click;
继续刨根问底,查看EventHandler的定义:
using System.Runtime.InteropServices;
namespace System
{
// 摘要:
// Represents the method that will handle an event that has no event data.
//
// 参数:
// sender:
// The source of the event.
//
// e:
// An System.EventArgs that contains no event data.
[Serializable]
[ComVisible(true)]
publicdelegatevoid EventHandler(object sender, EventArgs e);
}
看到了吧,就是委托!
转载请注明来自菩提树下的杨过http://www.cnblogs.com/yjmyzz/archive/2009/11/23/1608818.html
Delegate,Action,Func,匿名方法,匿名委托,事件 (转载)的更多相关文章
- C#-委托 lambda 匿名方法 匿名类型
1.lambda 匿名方法 匿名类型 delegate void d1(); d1 d = delegate(){Console.WriteLine("this is a test" ...
- (C#) Action, Func, Predicate 等泛型委托
(转载网络文章) (1). delegate delegate我们常用到的一种声明 Delegate至少0个参数,至多32个参数,可以无返回值,也可以指定返回值类型. 例:public del ...
- Delegate,Action,Func,匿名方法,匿名委托,事件
一.委托Delegate 一般的方法(Method)中,我们的参数总是string,int,DateTime...这些基本的数据类型(或者没有参数),比如 public void HelloWorld ...
- 委托-异步调用-泛型委托-匿名方法-Lambda表达式-事件【转】
1. 委托 From: http://www.cnblogs.com/daxnet/archive/2008/11/08/1687014.html 类是对象的抽象,而委托则可以看成是函数的抽象.一个委 ...
- C# 委托应用总结(委托,Delegate,Action,Func,predicate)
C# 委托应用总结 一.什么是委托 1.1官方解释 委托是一种定义方法签名的类型.当实例化委托时,您可以将其实例与任何具有兼容签名的方法相关联.您可以通过委托实例调用方法. 1.2个人理解 委托就是执 ...
- 委托delegate,Action,Func,Predicate
C#委托的介绍(delegate.Action.Func.predicate) 委托是一个类,它定义了方法的类型,使得可以将方法当作另一个方法的参数来进行传递.事件是一种特殊的委托. 1.委托的声明 ...
- Delegate,Action,Func,Predicate的使用与区别
C#4.0推出后,类似Linq,Lamda表达式等许多新的程序写法层次不穷.与之相关的Delegate,Action,Func,Predicate的使用和区别也常常让大家迷惑,此处就结合实际的应用,对 ...
- c# action<> func<> 这2个委托怎么用和理解
其实很好理解的呢!~首先你需要明白,他们是委托的简写形式. 一.[action<>]指定那些只有输入参数,没有返回值的委托 1.1定义一个委托: 比如,我们原来写委托: public de ...
- 温故而知新:Delegate,Action,Func,匿名方法,匿名委托,事件
Tks: http://www.cnblogs.com/yjmyzz/archive/2009/11/23/1608818.html 20150801 add: http://www.cnblogs. ...
随机推荐
- django admin后台显示中文
在settings中设置 LANGUAGE_CODE = ‘zh-Hans’
- java搭建web从0-1(第一步:创建web工程)
intellij idea版本:2017 1.新建一个web工程 使用工具intellij ideal,注意:只有Ultimate版本的可以新建web工程,社区版本的不支持新建web工程 File ...
- android 区分wifi是5G还是2.4G(转)
http://bbs.csdn.net/topics/391033966?page=1 我一开始看这帖子,找不到答案,为了后来的人,我来回复吧.WifiManager wifiManager = (W ...
- eclipse启动tomcat后,无法通过路径访问项目
eclipse已启动,访问localhost:8080也出现了tomcat页面,但是无法通过项目路径去访问项目,解决办法: 在控制台区域打开tomcat server,默认是第一项,且无法修改: 先把 ...
- poj1019(打表预处理+数学)
题目链接:http://poj.org/problem?id=1019 题意:对于序列1121231234...,求第i个数字(i<=2147483647). 思路:记第一组为1,第二组为12, ...
- 三星笔记本安装系统时报错:image failed to verify with * access denied* press any key to continue.
安装系统从光盘启动报错: 出现黑屏,并且有一个提示框image failed to verify with *access denied*press any key to continue 原因:三星 ...
- Python+Selenium学习--打印当前页面的title及url
场景 测试中,访问1个页面然后判断其title是否符合预期是很常见的1个用例,所谓用例不够,title来凑就是这个道理.更具体一点,假设1个页面的title应该是'hello world', 那么可以 ...
- jQuery Grid高级指南
上周以为已经把jqgrid 表格这部分已经搞得差不多了,没想到在实际用的时候,出现了不少问题,重新把这块知识整理一下. 问题一:设置表格的自动刷新 问题的原因: 使用表格自带的增删改查的功能,编辑完数 ...
- 将图片转换为Base64编码的字符串
图片以文件的形式存在,可以在表单中使用. 也可以转换成Base64编码的字符串,从而在css.js中以字符串的形式使用图片.例如,在css中设置背景图片.在js中用ajax上传图片. <!DOC ...
- 微信小程序开发——活动规则类文案文件读取及自动转换为小程序排版代码
前言: 最近做的小程序活动规则内容比较多,且一直处于修改中.由于小程序并不支持类似Html5中的预排版,所以,活动规则内容修改较大的时候,仍需要对新的内容用小程序的<text>组件做下排版 ...