委托、事件、接口等之间的关系和区别[转载]

Delegate Mail View
发件人 : Arty Yu
发送时间 :2006年5月24日星期三 20:35
收件人 : Timmy Wang; Jammy Zhang; Justin Sun; Hunter Yu; Harrison Jiang; Charley Chen; Little Ge
抄送 : Harry G Wang; Lynn Yu; Susan Wang; Van Fan; windy xu; Ann Tian
主题 : 答复 : 基本知识积累计划
Dear All,
经过初步讨论,总结一下 delegate
定义:
Delegate :具有相同参数和返回值(签名)的一类函数声明,这样比较通俗易懂
澄清一些概念:
Delegate 异步回调: Delegate 同步调用这个好理解,就是直接调用 Delegate 委托的方法; Delegate 可用于异步回调,首先强调可用于三个字,还有异步是异步,回调是回调,
概念不要混淆(异步回调可以作为后续 Study 技术点);
Delegate 多态 :概念截然不一样
Delegate 接口 :概念截然也不一样
主要运用:
异步回调 :感觉函数作为参数调用还非 Delegate 不可了(指 C#
事件的运用:用处很多(推荐后续 Study 技术点)
Thanks!
Arty
________________________________
发件人 : Timmy Wang
发送时间 : 2006年5月24日 19:24
收件人 : Timmy Wang; Arty Yu; Jammy Zhang; Justin Sun; Hunter Yu; Harrison Jiang; Charley Chen; Little Ge
抄送 : Harry G Wang; Lynn Yu; Susan Wang; Van Fan; windy xu; Ann Tian
主题 : 答复 : 基本知识积累计划
刚才的代码修正一下(异步委托的例子),可以
在控制台里写出来更能看出效果:
delegate int Add(int intA,int intB);
private void button5_Click(object sender, System.EventArgs e)
{
Console.WriteLine("begin--");
new Add(TestAdd).BeginInvoke(1,2,new System.AsyncCallback(TestAddBack),""); // 这里实现异步委托
Console.WriteLine("end--");
}
private int TestAdd(int intA, int intB)
{
return intA+intB;
}
private void TestAddBack(System.IAsyncResult o)
{
Add add = (Add)((System.Runtime.Remoting.Messaging.AsyncResult)o).AsyncDelegate;
Console.WriteLine("TestAddBack");
Console.WriteLine(add.EndInvoke(o).ToString());
Console.WriteLine(add(1,4).ToString());
}
输出结果:
begin--
end--
TestAddBack
3
5
Thanks
HI1/Timmy Wang
________________________________
发件人 : Timmy Wang
发送时间 : 2006年5月24日 18:38
收件人 : Arty Yu; Jammy Zhang; Justin Sun; Hunter Yu; Harrison Jiang; Charley Chen; Little Ge
抄送 : Harry G Wang; Lynn Yu; Susan Wang; Van Fan; windy xu; Ann Tian
主题 : 答复 : 基本知识积累计划
写了个小例子利用委托的回调:
private void button5_Click(object sender, System.EventArgs e)
{
new Add(TestAdd).BeginInvoke(1,2,new System.AsyncCallback(TestAddBack),""); // AsyncCallback 这个其实也是个委托
}
private void TestAdd(int intA, int intB)
{
System.Threading.Thread.Sleep(10000);
MessageBox.Show("TestAdd OK!");
}
private void TestAddBack(System.IAsyncResult o)
{
MessageBox.Show("callback OK!");
}
Thanks
HI1/Timmy Wang
________________________________
不知道是不是异步调用 :(
好像不是 :(
________________________________
发件人 : Hunter Yu
发送时间 : 2006年5月24日 13:07
收件人 : Timmy Wang; Justin Sun; Arty Yu; Harrison Jiang; Charley Chen; Jammy Zhang; Little Ge
抄送 : Harry G Wang; Lynn Yu; Susan Wang; Van Fan; windy xu; Ann Tian
主题 : 答复 : 基本知识积累计划
大家对 delegate 讨论的挺热烈嘛,刚才才看到,不过我对下面的说法不赞同。
" 这里 delgate function 都必须返回 void ,因为我们无法在多点传输中存储返回值。 "
delegate 说白了就是指针的转移,可以实现 callback 功能,但是 .net 却在它上面做了更多的发挥,允许用户可以为每一次的 callback 创建一个单独的线程,通过这种方式可以实现 function 的异步调用,至于上下面说的只能返回 void ,建议查一下 IAsyncResult 就知道了。
以上纯属个人观点:)
________________________________
发件人 : Timmy Wang
发送时间 : 2006年5月24日 9:45
收件人 : Justin Sun; Arty Yu; Hunter Yu; Harrison Jiang; Charley Chen; Jammy Zhang; Little Ge
抄送 : Harry G Wang; Lynn Yu; Susan Wang; Van Fan; windy xu; Ann Tian
主题 : 答复 : 基本知识积累计划
Justin 的例子刚好演示了 +/- 运算符在委托中的运用,
委托对象的一个有用属性是,它们可以 “+” 运算符来组合。组合的委托可调用组成它的那两个委托。只有相同类型的委托才可以组合。
“-” 运算符可用来从组合的委托移除组件委托。
// compose.cs
using System;
delegate void MyDelegate(string s);
class MyClass
{
public static void Hello(string s)
{
Console.WriteLine("Hello, {0}!", s);
}
public static void Goodbye(string s)
{
Console.WriteLine("Goodbye, {0}!", s);
}
public static void Main()
{
MyDelegate a, b, c, d;
// Create the delegate object a that references
// the method Hello:
a = new MyDelegate(Hello);
// Create the delegate object b that references
// the method Goodbye:
b = new MyDelegate(Goodbye);
// The two delegates, a and b, are composed to form c:
c = a + b;
// Remove a from the composed delegate, leaving d,
// which calls only the method Goodbye:
d = c - a;
Console.WriteLine("Invoking delegate a:");
a("A");
Console.WriteLine("Invoking delegate b:");
b("B");
Console.WriteLine("Invoking delegate c:");
c("C");
Console.WriteLine("Invoking delegate d:");
d("D");
}
}
输出
Invoking delegate a:
Hello, A!
Invoking delegate b:
Goodbye, B!
Invoking delegate c:
Hello, C!
Goodbye, C!
Invoking delegate d:
Goodbye, D!
Thanks
HI1/Timmy Wang
________________________________
发件人 : Justin Sun
发送时间 : 2006年5月24日 9:40
收件人 : Arty Yu; Timmy Wang; Hunter Yu; Harrison Jiang; Charley Chen; Jammy Zhang; Little Ge
抄送 : Harry G Wang; Lynn Yu; Susan Wang; Van Fan; windy xu; Ann Tian
主题 : 答复 : 基本知识积累计划
委托的定义是清楚啦,
但是会在什么样的场合下运用呢?为什么要运用呢,有什么好处呢?
让我们来看看。
委托常用的一个方向就是实现事件,这个以后讨论事件的时候再讨论。
另外单独运用委托的有没有呢?
有:这里我恰好有一个例子。
替换在 Regex <ms-help://MS.VSCC.2003/MS.MSDNQTR.2003FEB.2052/cpref/html/frlrfsystemtextregularexpressionsregexclasstopic.htm> 构造函数中指定的正则表达式所定义的字符模式的所有匹配项。在每个匹配处均调用 MatchEvaluator <ms-help://MS.VSCC.2003/MS.MSDNQTR.2003FEB.2052/cpref/html/frlrfsystemtextregularexpressionsmatchevaluatorclasstopic.htm> 委托以计算替换。
[C#]
public string <ms-help://MS.VSCC.2003/MS.MSDNQTR.2003FEB.2052/cpref/html/frlrfsystemstringclasstopic.htm>Replace(
string <ms-help://MS.VSCC.2003/MS.MSDNQTR.2003FEB.2052/cpref/html/frlrfsystemstringclasstopic.htm>input,
MatchEvaluator <ms-help://MS.VSCC.2003/MS.MSDNQTR.2003FEB.2052/cpref/html/frlrfsystemtextregularexpressionsmatchevaluatorclasstopic.htm>evaluator
);
这里 MatchEvaluator 就是一个委托,其实现一种约束,该约束就是 evaluator 可以 delegate 一种方法,该方法传入一个 Match 为参数,
String 为结果返回。这一点的行为有点类似于一个接口
这里看看使用委托的特点:
1. 首先我们只用按要求实现一个方法并创建一个 delegate 就可以运用了,不需要通过继承(或者说实现)接口。
2. 我们不需要去关心传入参数和返回结果,其实这里不是不用关心,只不过都被封装在 replace 中了,
3. 毫无疑问,这是一种回调。
另外 delegate 还有一个很奇妙的运用 多点传输
我们用停车这一个动作来看看:
我想这个动作可以分解为 松油门( RelAcc ),踩刹车 (SkidCar) ,关电等等这些小动作,我们当然可以写一个函数去调用这些动作。
当然我们可以用多点传输,使用一个 delegate 去调用多个 function ,(这里 delgate function 都必须返回 void ,因为我们无法在多点传输中
存储返回值。)
例子如下
using System;
namespace MultiTansfer
{
class Class1
{
static void Main(string[] args)
{
DoAction RelAccAction = new DoAction(ReleaseAcc);
DoAction SkidCarAction = new DoAction(SkidCar);
DoAction DoEnd = RelAccAction + SkidCarAction ;
DoEnd ();// 调用这个动作实现了两个动作
}
private static void ReleaseAcc()
{
for( int i = 0 ; i < 10; i ++)
{
Console.WriteLine("ReleaseAcc " + i.ToString());
}
}
private static void SkidCar()
{
for( int i = 0 ; i < 10; i ++)
{
Console.WriteLine("SkidCar " + i.ToString());
}
}
}
public delegate void DoAction();// 定义
}
以上都属于个人理解,任何错误和疑问可以指出讨论,所有说法只能参考,呵呵。
________________________________
发件人 : Arty Yu
发送时间 : 2006年5月24日 9:01
收件人 : Timmy Wang; Hunter Yu; Harrison Jiang; Charley Chen; Jammy Zhang; Justin Sun; Little Ge
抄送 : Harry G Wang; Lynn Yu; Susan Wang; Van Fan; windy xu; Ann Tian
主题 : 答复 : 基本知识积累计划
以下摘自 20060328pm--Modern C#(11) :深入 委托和事件 ”.pdf
定义:
MS 定义比较正宗拉,个人认为下面的定义也不错,通熟容懂!
委托和接口的区别,听讲师的讲的,还是比较疑惑的,个人认为
首先两个概念和用途上差异还是很明显的,相象点一是具备相同的签名,接口更为严格,实现
函数和接口声明一摸一样,二是怎样回调实现函数,有异曲同工的感觉, MS 内核实现我们可以猜测猜测
委托和接口的使用上资料上列的还是比较多的
先说这么些,欢迎提出非议;同时大家有问题或见解说好了,说错说对并不重要,下午会综合大家的想法达成一定认识
Continued…
________________________________
发件人 : Timmy Wang
发送时间 : 2006年5月24日 8:12
收件人 : Arty Yu; Hunter Yu; Harrison Jiang; Charley Chen; Jammy Zhang; Justin Sun; Little Ge
抄送 : Harry G Wang; Lynn Yu; Susan Wang; Van Fan; windy xu; Ann Tian
主题 : 答复 : 基本知识积累计划
delegate 声明定义一种引用类型,该类型可用于将方法用特定的签名封装。委托实例封装静态方法或实例方法。委托大致类似于 C++ 中的函数指针;但是,委托是类型安全和可靠的。
声明采用下列形式:
[attributes] [modifiers] delegate result-type identifier ([formal-parameters]);
其中:
attributes (可选)
附加的声明性信息。有关属性和属性类的更多信息,请参见 17. 属性。
modifiers (可选)
允许使用的修饰符有 new 和四个访问修饰符。
result-type
同方法的返回类型匹配的结果类型。
identifier
委托名称。
formal-parameters (可选)
参数列表。如果参数是一个指针,则必须用 unsafe 修饰符声明委托。
备注
委托使您得以将函数作为参数传递。委托的类型安全要求作为委托传递的函数拥有同委托声明相同的签名。请参见委托教程了解有关使用委托的更多信息。
委托教程 显示了如何撰写委托,即如何从其他委托创建委托。不能撰写包含 out 参数的委托。
委托是事件的基础。
有关委托的更多信息,请参见 15. 委托。
示例 1
以下是声明及使用委托的一个简单示例。
// keyword_delegate.cs
// delegate declaration
delegate void MyDelegate(int i);
class Program
{
public static void Main()
{
TakesADelegate(new MyDelegate(DelegateFunction));
}
public static void TakesADelegate(MyDelegate SomeFunction)
{
SomeFunction(21);
}
public static void DelegateFunction(int i)
{
System.Console.WriteLine("Called by delegate with number: {0}.", i);
}
}
输出
Called by delegate with number: 21.
示例 2
在下例中,一个委托被同时映射到静态方法和实例方法,并分别返回特定的信息。
// keyword_delegate2.cs
// Calling both static and instance methods from delegates
using System;
// delegate declaration
delegate void MyDelegate();
public class MyClass
{
public void InstanceMethod()
{
Console.WriteLine("A message from the instance method.");
}
static public void StaticMethod()
{
Console.WriteLine("A message from the static method.");
}
}
public class MainClass
{
static public void Main()
{
MyClass p = new MyClass();
// Map the delegate to the instance method:
MyDelegate d = new MyDelegate(p.InstanceMethod);
d();
// Map to the static method:
d = new MyDelegate(MyClass.StaticMethod);
d();
}
}
输出
A message from the instance method.
A message from the static method.
Thanks
HI1/Timmy Wang
________________________________
发件人 : Arty Yu
发送时间 : 2006年5月23日 18:24
收件人 : Hunter Yu; Harrison Jiang; Charley Chen; Jammy Zhang; Justin Sun; Little Ge; Timmy Wang
抄送 : Harry G Wang; Lynn Yu; Susan Wang; Van Fan; windy xu; Ann Tian
主题 : 答复 : 基本知识积累计划
别忘了,明天早上。。。
________________________________
发件人 : Hunter Yu
发送时间 : 2006年5月22日 16:29
收件人 : Arty Yu; Harrison Jiang; Charley Chen; Jammy Zhang; Justin Sun; Little Ge; Timmy Wang
抄送 : Harry G Wang; Lynn Yu; Susan Wang; Van Fan; windy xu; Ann Tian
主题 : 答复 : 基本知识积累计划
Modern C#(11) :深入 委托和事件
http://www.microsoft.com/china/msdn/events/webcasts/shared/webcast/episode.aspx?newsID=1242465
________________________________
发件人 : Arty Yu
发送时间 : 2006年5月22日 16:20
收件人 : Harrison Jiang; Charley Chen; Jammy Zhang; Justin Sun; Little Ge; Timmy Wang; Arty Yu
抄送 : Harry G Wang; Hunter Yu; Lynn Yu; Susan Wang; Van Fan; windy xu; Ann Tian
主题 : 答复 : 基本知识积累计划
找到两个讲解委托不错的地方 http://www.pconline.com.cn/pcedu/empolder/net/cs/0311/237203.html
http://finesite.cnblogs.com/archive/2006/02/17/255884.html
供参考之
________________________________
发件人 : Arty Yu
发送时间 : 2006年5月19日 17:36
收件人 : Harrison Jiang; Charley Chen; Jammy Zhang; Justin Sun; Little Ge; Timmy Wang
抄送 : Harry G Wang; Hunter Yu; Lynn Yu; Susan Wang; Van Fan; windy xu; Ann Tian
主题 : 答复 : 基本知识积累计划
Dear All,
基本知识积累计划活动下周拉开序幕了,我先开始吧:
话题:认识 C#— 委托 ( 委托的产生背景,原理,应用。。。 )
原则:基于基础,专注技术点,应用与理论达到平衡
形式:争论,再争论
结果:结果并不重要,主要我们大家能达成共识,如果 2 天时间不够,希望后续主导人延续这个话题
时间: 2 天内每个人只需要花费 1-2 小时 Study 就可以了,工作时间还是业余时间由自己掌握。
Thanks!
Arty
________________________________
发件人 : Harrison Jiang
发送时间 : 2006年5月17日 13:58
收件人 : Arty Yu; Charley Chen; Jammy Zhang; Justin Sun; Little Ge; Timmy Wang
抄送 : Harry G Wang; Hunter Yu; Lynn Yu; Susan Wang; Van Fan; windy xu; Ann Tian
主题 : 基本知识积累计划
Dear All,
先前我们有提到,我们 R Team 在近段时间内需提高所有 Team 成员的技术水平,
但是到目前为止还没看到任何活跃的迹象。
我们都做的不够!
以下是我的计划:
1 、该计划以分享和自我 Study 的方式进行;
2 、每 2 天为 1 个技术点,技术点要足够的细,比如:不要是 学习类 ,应该是 学习类的继承 或者更 Detail 的点;
3 、技术点的主导人员在 R Team 中采用轮换的方式进行;
4 、总结方式或分享方式由主导人员来定,不要超过 30 分钟,如果是有价值的讨论,可以例外;
5 、不管用哪种方式结束,我们都需要保留一份文档;
6 、计划从下周一开始,第一个人员是 Arty
7 、近期的知识点选择,尽量是在我们工作中能用到的。
目的:日积月累,提高技术能力。
有什么想法尽管提!
淡泊以明志,寧靜以致遠
Harrison Jiang
R&D Center Hi1
BenQ (IT) Co.,Ltd.
268 Shishan Road ,New District Suzhou,China
HarrisonJiang@BenQ.com.cn <mailto:HarrisonJiang@BenQ.com.cn>
tel: +86-512-68251233-6599
WEB Page :
http://blog.csdn.net/OceanChild <http://blog.csdn.net/OceanChild>
发件人 : Arty Yu
发送时间 :2006年5月24日星期三 17:03
收件人 : Jammy Zhang; Justin Sun; Hunter Yu; Timmy Wang; Harrison Jiang; Charley Chen; Little Ge
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值