C#委托和事件详解第二篇

[来源] 达内    [编辑] 达内   [时间]2012-09-17

这篇博客是在上篇的基础开始讲述了一下委托的一些用法,首先我举一个例子说明了一下前面章节的知识点,接下来我说了将方法作为参数传递的一个案例,接下来实现了一个委托实现冒泡排序的方法,如果你们和我一样正在学习,希望能够把代码详细的看一下,我感觉还是有帮助的,最后讲...

前言: 这篇博客是在上篇的基础开始讲述了一下委托的一些用法,首先我举一 个例子说明了一下前面章节的知识点,接下来我说了将方法作为参数传递的一个案例,接下来实现了一个委托实现冒泡排序的方法,如果你们和我一样正在学习,希望能够把代码详细的看一下,我感觉还是有帮助的,最后讲述一下回调函数的例子,学习编程做好的方法就是从代码中学习,所以我列举了很多代码,希望我们共同学习

1. 新建一个项目

(1)新建一个控制台项目,实现利用委托来实现多态的实现,

(2)委托可以将方法定义成变量来使用,所以可以实现统一调用不同实现

(3)举例说明一下:记得大学的时候老师让我们做过一个面试题,说是用委托实现如下功能,主人回家了,灯亮了,猫叫了,老鼠被逮着了,iphone5S 出来了,有人有少肾了 ,下面我就写一下这道题的代码吧

 

 1

   public delegate
 

void FuncDelagete();  2
 
 3     class
 Program  4
 
 5     { 
 6
 
 7         static
 void Main(string
[] args) 

 8
 
 9         { 
10
 
11             Console.Write("
请选择1:主人,2猫,3Iphone:"
); 12
 
13            //
定义一个委托变量

14 
15             FuncDelagete GetChoose; 
16
 
17             //
就是装配委托变量的方法

18 
19             switch
 (Console.ReadLine()) 20
 
21             { 
22
 
23                 case
 "1
"

: 24
 
25                     GetChoose = Master; 
26
 
27                     break
; 28
 
29                 case
 "2
"

: 30
 
31                     GetChoose = Cat; 
32
 
33                     break
; 34
 
35                 case
 "3
"

: 36
 
37                     GetChoose = Iphone; 
38
 
39                     break
; 40
 
41                 default
: 42
 
43                     GetChoose = null
; 44
 
45                     break
; 46
 
47             } 
48
 
49             //
调用委托变量指向的方法,如果没有指向什么也不做

50 
51             if
 (GetChoose != null) 
52

 
53             { 
54
 
55                 GetChoose(); 
56
 
57             } 
58
 
59             Console.ReadKey(); 
60
 
61         } 
62
 
63         public
 static void
 Master() 

64
 
65         { 
66
 
67             Console.WriteLine("
主人回家了,灯亮了"
); 68
 
69         } 
70
 
71         public
 static void
 Cat() 

72
 
73         { 
74
 
75             Console.WriteLine("
猫叫了,老鼠被逮着了"
); 76
 
77         } 
78
 
79         public
 static void
 Iphone() 

80
 
81         { 
82
 
83             Console.WriteLine("
iphone出来了,有人有少肾了"
); 84
 
85         } 
86
 
87     }

2. 将方法作为参数传递使用,先举个例子如下:

    

 1

 public delegate
 void

 FuncDelegate();  2
 
 3     class
 Program  4
 
 5     { 
 6
 
 7         static
 void Main(string
[] args) 

 8
 
 9         { 
10
 
11             FuncDelegate myFunc = new
 FuncDelegate(Func); 12
 
13             Chinese(myFunc); 
14
 
15             //
等价于Chinese(Func); 16
 
17 //
等价于Chinese(new FuncDelegate(Func));

18 
19             Console.ReadKey(); 
20
 
21         } 
22
 
23         //
原始的,需要被当作参数来传递的

24 
25         public
 static void
 Func() 

26
 
27         { 
28
 
29             Console.WriteLine("
钓鱼岛是我们的,就是我们的参数,我们要传到中国去"
); 30
 
31         } 
32
 
33         //
传入什么方法,就直接执行这个方法

34 
35         public
 static void
 Chinese(FuncDelegate target) 

36
 
37         { 
38
 
39             if
 (target != null) 
40

 
41             { 
42
 
43                 target(); 
44
 
45             } 
46
 
47         } 
48
 
49     }

    //注:这只是一个演示的小案例,举得例子感觉有点不太好,但是因为这段时间是特殊日期吗,能看懂就行

说明:

(1) 将方法作为一个参数,传到另一个方法中执行,那么另一方法就可以作为一个执行的载体,他不管具体要干什么,只考虑自己的独有逻辑,可变化的方法有传入的方法执行

(2) 下面我们考虑这样一个练习:用冒泡对一个字符串进行排序,用数字的形式去排序, 按照字符串的长度去排序 ,如果我们不使用委托事项的话我们的代码可以这样写,当然写出这个程序的代码很多,我就只按照我的写一遍

  1

 class Program 
  2

 
  3     { 
  4
 
  5         static
 void Main(string
[] args) 

  6
 
  7         { 
  8
 
  9             string
[] strArr = { "232
"

, "43
", "
65

", "
76

", "
87"
, "

46"


 };  10
 
 11             //
用冒泡对这个字符串进行排序  12
 
 13             //
用数字的形式去排序  14
 
 15             //
按照字符串的长度去排序

 16 
 17             OrderNum(strArr); 
 18
 
 19             OrderString(strArr); 
 20
 
 21  
 22 
 23             Console.ReadKey(); 
 24
 
 25         } 
 26
 
 27         //
按照数字的方式去排序

 28 
 29         public
 static void
 OrderNum(string

[] nums)  30
 
 31         { 
 32
 
 33             for
 (int i = 0
; i < nums.Length - 1

; i++)  34
 
 35             { 
 36
 
 37                 for
 (int j = 0
; j < nums.Length - 

1 - i; j++)  38
 
 39                 { 
 40
 
 41                     if
 (Convert.ToInt32(nums[j]) > Convert.ToInt32(nums[j + 1])) 
 42
 
 43                     { 
 44
 
 45                         string
 temp = nums[j];  46
 
 47                         nums[j] = nums[j + 1
];  48
 
 49                         nums[j + 1
] = temp;  50
 
 51                     } 
 52
 
 53                 } 
 54
 
 55             } 
 56
 
 57         } 
 58
 
 59         //
按照字符串的方式排序

 60 
 61         public
 static void
 OrderString(string

[] nums)  62
 
 63         { 
 64
 
 65             for
 (int i = 0
; i < nums.Length - 1

; i++)  66
 
 67             { 
 68
 
 69                 for
 (int j = 0
; j < nums.Length - 

1 - i; j++)  70
 
 71                 { 
 72
 
 73                     if
 (string.Compare(nums[j], nums[j + 1
]) > 0) 
 74

 
 75                     { 
 76
 
 77                         string
 temp = nums[j];  78
 
 79                         nums[j] = nums[j + 1
];  80
 
 81                         nums[j + 1
] = temp;  82
 
 83                     } 
 84
 
 85                 } 
 86
 
 87             } 
 88
 
 89         } 
 90
 
 91     } 
 92
 
 93 
下面我用方法传参的方式写一下上面所实现的代码:代码如下:  94
 
 95 public
 delegate bool
 CompareDelegate(string

 s1,string s2); 
 96
 
 97     class
 Program  98
 
 99     { 
100
 
101         static
 void Main(string
[] args) 

102
 
103         { 
104
 
105             string
[] strArr = { "232
"

, "43
", "
65

", "
76

", "
87"
, "

46"


 }; 106
 
107             //
用冒泡对这个字符串进行排序 108
 
109             //
用数字的形式去排序 110
 
111             //
按照字符串的长度去排序

112 
113             Order(strArr, CompareNum); 
114
 
115             Order(strArr, CompareString); 
116
 
117             Console.ReadKey(); 
118
 
119         } 
120
 
121         //
通用方法对字符串数组进行排序,排序的规则有传入的方法决定

122 
123         public
 static void
 Order(string

[] nums,CompareDelegate target) 124
 
125         { 
126
 
127             for
 (int i = 0
; i < nums.Length - 1

; i++) 128
 
129             { 
130
 
131                 for
 (int j = 0
; j < nums.Length - 

1 - i; j++) 132
 
133                 { 
134
 
135                     if
 (target(nums[j], nums[j + 1])) 


136
 
137                     { 
138
 
139                         string
 temp = nums[j]; 140
 
141                         nums[j] = nums[j + 1
]; 142
 
143                         nums[j + 1
] = temp; 144
 
145                     } 
146
 
147                 } 
148
 
149             } 
150
 
151         } 
152
 
153         //
按照数字的方式去排序

154 
155         private
 static bool
 CompareNum(string

 str1, string str2) 
156
 
157         { 
158
 
159             return
 Convert.ToInt32(str1) > Convert.ToInt32(str2); 160
 
161         } 
162
 
163         //
按照字符串的方式排序

164 
165         private
 static bool
 CompareString(string

 str1, string str2) 
166
 
167         { 
168
 
169             return
 string.Compare(str1, str2) > 0
; 

170
 
171         } 
172
 
173 }

->方法作为参数传递-回调函数

(1)在回调函数里面私有方法照样被访问,下面我们通过一个例子来说明一下,这段代码要仔细的看哦,

由于跳转的很厉害,所以看不懂的话可以加断点实验一下:

  

 1

 public delegate
 void

 FuncDelagete();  2
 
 3 class
 Program  4
 
 5 { 
 6
 
 7     static
 void Main(string
[] args) 

 8
 
 9     { 
10
 
11         MyClassCol mc=new
 MyClassCol(); 12
 
13         mc.Initialize(); 
14
     
15         (); 
16
     
17         Console.ReadKey(); 
18
 
19     } 
20
 
21 } 
22 class
 MyClassCol 

23
 
24 { 
25
 
26     MyClass m; 
27
 
28     public
 void Initialize() 
29

 
30     { 
31
 
32         m = new
 MyClass(); 33
 
34          = Func; 
35
 
36     } 
37     public
 void

 Run() 38
 
39     {  
40
 
41         (); 
42
 
43     } 
44     private
 void

 Func() 45
 
46     { 
47
 
48         Console.WriteLine("
我是回调方法"


); 49
 
50     } 
51
 
52 } 
53
 
54 //
这个类实现回调

55 
56 class
 MyClass 57
 
58 { 
59
 
60     FuncDelagete target; 
61
 
62     public
 FuncDelagete Target 63
 
64     { 
65
 
66         get
 { return target; } 
67

 
68         set
 { target = value; } 69
 
70     } 
71
 
72     public
 void Run() 
73

 
74     { 
75
 
76         if
 (target != null) 
77

 
78         { 
79
 
80             target(); 
81
 
82         } 
83
 
84     } 
85
 
86 }

资源下载