为什么要写这篇文章
首先,想找个借口说英语很难,但是,我将尽可能的让这篇文章通俗易懂。
其次,我想解释一下我写这篇文章的原因。一段时间以前,我和一个朋友讨论过一个问题,他当时正在学习C#,他让我给他解释一下delegates和events。 当时,我非常地吃惊。 现在有那么多的C#书籍,有用的链接,sample源代码等等。但在讨论的过程中,我意识到他已经读过C#编程的书,浏览过很多有用的网络资源,也研究过一些好的代码实例, 但是对于理解delegates来说还是有不少的问题。
这个代码实例就是我们讨论的结果。这个例子非常地简单,也可以说,非常地无聊。但是,他让我的那位朋友理解了delegates的实质。我希望这个例子以及其中的注释对于其他正在学习C#的朋友也有用。
正文开始
我建议你在阅读这篇文章前先下载下来这个demo(演示)项目。是一个C#控制台应用程序。解压缩后,用.NET Studio打开那个.sln文件.
C# delegate 是一个callback函数。 换言之,delegate是class-server向class-client提供反馈的一种方式。
C# 的delegate要比一般的(标准的)callback函数更加的灵活,因为它允许你定义一系列(strict list)可以从class-server端到class-client端的参数。
在我们的这个例子中,class-server有一个名字DataHolder。它包含了一个数据集合。而数据项在DataItem类中进行的定义,每一个数据都有两个属性:Name和Color。而DataHoder类包含一个允许遍历查找数据集合以便找到符合搜索条件数据的方法。这个方法有两个参数,第一个参数定义了搜索的条件,第二个参数定义了一个当符合搜索条件时可以调用的方法。
正确的理解class-server端遍历所有的数据(from the start to the end)是非常重要的。如果数据项符合搜索条件,那么class-server端就调用一个class-client端定义的方法。返回数目也就和符合搜索条件的那些数据项目数目相同。
MainClass即是class-client.第一句话就创建了一个DataHolder类的实例(1st),然后创建了CallBack类型逆光的delegate实例。这个delegate实例(procedure01) 包含了下面的信息:用户自定义的class-server段要在class-client端调用的方法(PrintSearchResult),并且class-server必须把这些参数传递给这个用户定义的参数.而传递的这个参数,是在delegate声明中定义的。
以上就是C# delegate的主要思想。我建议你把这段代码在编译器中执行一遍看看他的执行结果。
===================================
部分代码:
2 {
3 private string m_ObjectName;
4 private string m_Color;
5
6 public DataItem(string Name, string Color)
7 {
8 m_ObjectName = Name;
9 m_Color = Color;
10 }
11
12 public string Name
13 {get {return m_ObjectName;}}
14
15 public string Color
16 {get {return m_Color;}}
17
18 }//Class Item
19
20 /*This is declaration of new data type "CallBack" which is based
21 * on C# data type "delegate"*/
22 public delegate void CallBack(string s);
23
24
25 /*This class represents collection of data items.*/
26 class DataHolder
27 {
28 private ArrayList m_List;
29
30 public DataHolder()
31 {
32 m_List = new ArrayList();
33 m_List.Add(new DataItem("Desk", "Black"));
34 m_List.Add(new DataItem("Car", "Red"));
35 m_List.Add(new DataItem("Train", "Yellow"));
36 m_List.Add(new DataItem("Tomato", "Red"));
37 m_List.Add(new DataItem("Cheese", "Yellow"));
38 m_List.Add(new DataItem("Computer","Grey"));
39 m_List.Add(new DataItem("Sausage", "Red"));
40 m_List.Add(new DataItem("Cat", "Black"));
41 }
42
43 /* this method provides search functionality for caller. When an item
44 * meets search condition is found, client defined procedure activates.*/
45 public void SearchData(string SearchCondition, CallBack ClientDefinedProcedure)
46 {
47 foreach (DataItem i in this.m_List)
48 {
49 if (i.Color == SearchCondition)
50 {
51 ClientDefinedProcedure(i.Name);
52 }
53 }
54 }
55 }//Class DataHolder
56
57
58 class MainClass
59 {
60 [STAThread]
61 static void Main(string[] args)
62 {
63 /*Create list of Data Items*/
64 DataHolder lst = new DataHolder();
65
66 /* Cteate instance of delegate with type CallBack and bind it
67 * to user defined procedure PrintSearchResults()*/
68 CallBack procedure01 = new CallBack(PrintSearchResult);
69
70 Console.WriteLine("Red color objects:");
71 /*Call search method with search critheria "Red" and user defined
72 * procedure which is nesessary to execute when data item meets to search
73 * creteria is found.*/
74 lst.SearchData("Red", procedure01);
75 Console.WriteLine("---------------");
76 Console.ReadLine();
77
78 }
79
80 /*This procedure is called by DataHolder any time when data item meets to search
81 * criteria is found.*/
82 private static void PrintSearchResult(string s)
83 {
84 Console.WriteLine(s);
85 }
86 }//MainClass
Red color objects:
Car
Tomato
Sausage
-------------