C# Delegate的用法之一

Posted on 2004-12-13 02:56 Ray Chang 阅读(5221) 评论(11)  编辑 收藏 所属分类: .NET

C# Delegate的用法之一


常建昭

前一阵子曾经讨论了关于在一个
winform中调用另一个winform的方法,里面提到要做到这一功能,最好的方法是利用Delegate,一些朋友也在回复中提到,Google同学早就发出信息,可怜俺到最后用到才知,不过值的庆幸的是,知识还是学到手了,对于别人可能是个笑话,但对于我自己,是种进步。呵呵,不求与人相比,只求超越自己。。

 

Ok,闲话少说,现在将我对Delegate的一些理解摆上来让大家PP,如果有错,还请大家更正

 

注: 在网上有着许多Delegate的知识和介绍文章,有很多写的非常的详细。我这篇只是我自己对Delegate使用的看法,不保证完全正确。如果误导了你,可别怪我哦。

 

网上一搜,关于Delegate的中文介绍最热门的估计是Stanley B. LippmanC Primer的作者)的翻译版。给个链接,让有需要的朋友可以参考一下。http://www.chinaaspx.com/article/csharp/355.htm (中国DotNet俱乐部提供)

 

 

首先来看看Delegate的定义:

A delegate declaration defines a reference type that can be used to encapsulate a method with a specific signature. A delegate instance encapsulates a static or an instance method. Delegates are roughly similar to function pointers in C++; however, delegates are type-safe and secure.

                                                                      ――转自 MSDN的网站

 

上面的定义解释了一个delegate的声明定义了一个reference type, 而这个reference type是用来将一个方法利用一个指定的形式压缩起来。一个delegate的实例压缩一个静态或者一个实例方法。DelegatesC++中的功能指针很相似。然而,不同的是,delegate是安全的,并且是Type-safe.

 

我初看这个定义的时候,觉的怪怪的,因为那时完全不明白什么是type-safe,而且小弟没接触过C++,除了知道有个指针,还就什么都不知道了。好在有Google兄弟,下面这二个定义应该能帮助我们更好的了解Delegate.

这二个定义是在codeProject网站中找到的。

C# delegate is a callback function. In other words, delegate is a way to provide feedback from class-server to class-client.

C#delegate是一种callback功能。换句话说,delegate是一种从类的服务端向类的客户端提供反馈的一种途径。

C# delegate is smarter then “standard” callback because it allows defining a strict list of parameters which are passed from class-server to class-client

但是C# delegate却比一般的callback 功能要更聪明。因为它允许定义一个严格的参数列表。而这个参数列表则包含着从类的服务端向类的客户端把传递的参数。

Lippman 的文章中,他解释了三点C# delegateC++指针的不同的地方。个人认为解释的非常好,对于理解delegate有很大帮助。现贴在这里,有助大家“消化”。


C#
Delegate Type
Delegate
是一种函数指针,但与普通的函数指针相比,区别主要有三:

1)
一个 delegate object 一次可以搭载多个方法(methods),而不是一次一个。当我们唤起一个搭载了多个方法(methods)的 delegate,所有方法以其被搭载到 delegate object 的顺序被依次唤起——稍候我们就来看看如何这样做。

2)
一个 delegate object 所搭载的方法(methods)并不需要属于同一个类别。一个 delegate object 所搭载的所有方法(methods)必须具有相同的原型和形式。然而,这些方法(methods)可以即有 static 也有 non-static,可以由一个或多个不同类别的成员组成。

3)
一个 delegate type 的声明在本质上是创建了一个新的 subtype instance,该 subtype 派生自 .NET library framework abstract base classes Delegate MulticastDelegate,它们提供一组 public methods 用以询访 delegate object 或其搭载的方法(methods

 

下面是我结合在一个窗口中调用另一个窗口的实例来说明delegate的定义和用法:

定义delegate:

public void delegate FormHandler(string msg, Buddy buddy)

 

 

 

创建instance:

FormHandler formHandler = new FormHandler(string msg, Buddy buddy);

 

 

 

 

指定目标:

 

FormHandler = new FormHandler(FormShow);

 

 

 

 

显示form的方法:

 

public void FormShow (string msg, Buddy buddy)

{

         
if (!this.Invokerequired) //如果当前线程不是主UI线程,返回true,否则,返回false.

         
{

                   ChatForm cf 
= new ChatForm(msg, buddy); 

                   Cf.Show();
}


else

{

         FormHandler fHandler 
= new formHandler(ShowForm); //创建一个新instance指向formShow.

         This.BeginInvoker(showForm, 
new object[] {msg, buddy}); //启动delegate

}


}

 由上面的程序可以大概看的出如何定义和启动一个delegate,我用上面的方法成功的实现了在一个窗口中调用另一个窗口的功能。如果你有任何问题,可以给我发email,大家可以讨论讨论。

 

Feedback

#1楼    回复  引用    

2004-12-13 14:15 by Ninputer [未注册用户]
两个窗体之间调用,耦合最少,设计最简便,性能最好的方式是让两个窗体都成为Semi-Singleton,并提供统一的全局访问点。当然要用这种方式必须满足一定的条件,比如窗体做Singleton合适不合适等。

其他方法,通过Event,Delegate,或者静态的传递变量,全局变量,构造函数传递参数等,既不优美也不符合OO,而且窗体之间多了不该有的耦合。

#2楼    回复  引用    

2004-12-13 19:50 by yh [未注册用户]
写的非常好看,学习中,感谢!

#3楼    回复  引用    

2005-03-18 09:49 by hsq [未注册用户]
我是初学者,想请教几个问题:
程序中的buddy是什么类型?
ChatForm 又是在哪儿定义的,cf是另一个窗体的名称吗?
BeginInvoke又是什么,包含在某个using...中吗?

能把完整的程序代码展示出来吗?
谢谢

#4楼    回复  引用  查看    

2005-03-18 23:07 by Ray Chang      
程序中的buddy是什么类型?
A: buddy is an object, an instance of Buddy.

ChatForm 又是在哪儿定义的,cf是另一个窗体的名称吗?
A: ChatForm is simply a winform, and cf is the instance of this ChatForm

BeginInvoke又是什么,包含在某个using...中吗?
A: Here is a link to explain what is BeginInvoke..
http://msdn.microsoft.com/library/chs/default.asp?url=/library/CHS/cpref/html/frlrfsystemwindowsformscontrolclassbegininvoketopic.asp


#5楼    回复  引用    

2005-04-01 10:28 by jeal [未注册用户]
if (!this.Invokerequired) //如果当前线程不是主UI线程,返回true,否则,返回false.


这是你文章中的一句话,我想知道判断当前线程不是主UI线程依据是什么?如果这代码也是在一个Form中,ChatForm也是一个form,哪个是主UI线程?

我是一个菜鸟,多多指教。

#6楼 [楼主]   回复  引用  查看    

2005-04-02 04:39 by 常建昭      
我认为当一个Windows application执行时,Main UI Thread会开始执行。而调用Chatform的线程则是Worker thread(工作线程)或者说是辅助线程。this.Invokedrequired的判断是判断打开chatform是否是主线程调用的,我当初加这 个comment是为了更好的去理解
MSDN的这篇文章你可以看一下:
http://msdn.microsoft.com/library/chs/default.asp?url=/library/CHS/cpref/html/frlrfsystemwindowsformscontrolclassinvokerequiredtopic.asp

我也是菜鸟,大家互相学习。

#7楼    回复  引用  查看    

2005-04-21 11:59 by       
网页中ASP多个文件的函数传递我是不会的请各路高手指点

#8楼 [楼主]   回复  引用  查看    

2005-04-22 07:10 by 常建昭      
ASP我不熟悉,你说的多个文件的函数传递是指页面间的数值传递吗?

#9楼    回复  引用    

2005-10-08 10:02 by pop [未注册用户]
FormHandler formHandler =new FormHandler(FormShow);
就可以了

#10楼    回复  引用    

2005-10-13 18:14 by wenstar [未注册用户]
常老师:
有关delegate在二个winForm如何实行数据传递的,(例如当Form2:button_click时,把Form2的textbox的内容在Form1中显示)可否详细解释并给我一个例程?

谢谢先!

如可能,请把例程发到wenstar18@hotmail.com

#11楼    回复  引用    

2007-04-09 09:30 by Ray [未注册用户]
汗。。这年头,广告真是无处不在

标题  
姓名  
主页
Email (博主才能看到) 
验证码 *  看不清,换一张 [登录][注册]
内容(请不要发表任何与政治相关的内容)  
  博客园首页

  新闻频道

  社区

  小组

  博问

  网摘

  闪存

  登录  使用高级评论  新用户注册  返回页首  恢复上次提交      
该文被作者在 2008-04-10 15:19 编辑过


相关链接:
 



posts - 63, comments - 179, trackbacks - 5, articles - 8

Copyright © Ray Chang