委托与事件

学习目标:

委托的定义

掌握并熟练使用委托

多重委托的理解

事件的掌握

委托

 

委托就是可以对方法进行引用的类,与其他的类不同,委托类只对其匹配的方法进行引用,C#中委托是面向对象的,并且类型是安全的,委托方法的调用可以像任何其他方法一样,具有参数和返回值,但是分配给委托的方法必须与委托的返回类型和参数组成匹配,这里的方法可以是静态方法也可以是实例方法。

 

定义委托的语法类似于方法的定义,但是没有方法体,定义的前面要加上关键字delegate。

 

可以根据委托的可见性在委托定义上添加一般的访问修饰符:public、private和protected等

 

定义委托的语法:

 

public delegate void MyFirstDelegate(string message);

 

委托是只要定义就可以使用,并不需要关心它的实现。

 

委托的使用

 

委托相当于一个类,但是委托是一个值类型,使用委托就需要对委托进行实例化。实例化委托后,委托将把对它进行的方法调用传递给方法。调用方法传递给委托的参数被传递给方法,来自方法的返回值(如果有)由委托返回给调用方,称为调用委托。

 

示例:

View Code
 1 public delegate void MyFistDelegate(string message);//定义委托
2 class MyClass
3 {
4 public void WriteFistMessage(string message)
5 {
6 Console.WriteLine(message);
7 }
8 }
9 class Program
10 {
11 static void Main(string[] args)
12 {
13 MyClass myClass = new MyClass();
14 //实例化类型为MyFistDelegate的一个委托,引用对象myClass的WriteFistMessage方法
15 MyFistDelegate myFist = new MyFistDelegate(myClass.WriteFistMessage);
16 myFist("委托本身调用了委托");
17 }
18 }

运行结果:

委托作为参数的使用:委托调用静态方法时,由于实例化委托是一个对象,所以可以将其作为参数进行传递,也可以将其赋值给属性,这样方法便可以将一个委托作为参数来接受 ,并且以后可以调用该委托,这称为异步回调。

示例:

View Code
 1 namespace useDelegate
2 {
3 public delegate void MyDelegate(int i, int j);
4 class MyNewClass
5 {
6 public static void Sum(int i, int j)
7 {
8 int sum = i + j;
9 Console.WriteLine("和:{0}+{1}={2}", i, j, sum);
10 }
11 public static void Product(int i, int j)
12 {
13 int product = i * j;
14 Console.WriteLine("积:{0}*{1}={2}", i, j, product);
15 }
16 public static void MethodDelegate(int i, int j, MyDelegate myDelegate)//委托作为参数
17 {
18 myDelegate(i, j);
19 }
20 }
21 class Program
22 {
23 static void Main(string[] args)
24 {
25 MyNewClass.MethodDelegate(10, 10, MyNewClass.Sum);
26 MyNewClass.MethodDelegate(10, 10, MyNewClass.Product);
27 Console.ReadKey();
28 }
29 }
30 }

运行结果:

多重委托

多重委托:委托是一个特殊的对象,委托有一个用途在于可以使用“+”运算符将它们分配给一个要成为多路广播的委托实例。组合委托可调用组成它的那两个委托,只有相同类型的委托才可以组合,就像字符串相加:

string s="Hello";

s+="World";

如果委托可以使用+运算符,那么也可以使用“-”运算符:

下面创建一个关于多路广播委托的示例:

View Code
 1 delegate void MyDelegate(int i, int j);
2 class Program
3 {
4 static void Main(string[] args)
5 {
6 Program p = new Program();
7 MyDelegate del = new MyDelegate(p.Method);
8 del(10, 20);
9 Console.WriteLine("使用+运算符后,显示效果");
10 del += p.Methodl;
11 del(20, 20);
12 Console.WriteLine("使用-运算符后,显示效果");
13 del -= p.Method;
14 del(20, 20);
15 }
16 void Method(int i, int j)
17 {
18 Console.WriteLine("求和:{0}+{1}={2}", i, j, i + j);
19 }
20 void Methodl(int i, int j)
21 {
22 Console.WriteLine("求积:{0}*{1}={2}", i, j, i * j);
23 }
24 }

运行结果:

匿名方法和Lambda表达式

在委托中使用匿名方法就不必要创建单独的方法

实例化委托的两种方法

匿名方法示例:

View Code
 1 public delegate void MyDelegate(string s);
2 class MyTest
3 {
4 static void Main(string[] args)
5 {
6 MyDelegate myDel = delegate(string j)
7 {
8 System.Console.WriteLine(j);
9 };
10 myDel("使用匿名方法实例化委托");
11 myDel = new MyDelegate(MyTest.DoWork);
12 myDel("不使用匿名方法实例化委托");
13 Console.ReadKey();
14 }
15 static void DoWork(string k)
16 {
17 System.Console.WriteLine(k);
18 }
19 }

运行结果:

使用Lambda表达式

Lambda方法示例:

 

运行结果:

 

事件

事件是面向对象编程中常用的技术之一,是初始化程序元素之间通信动态格式的机制。

我们可以将事件编程简单的划分成两个部分:事件发生的类和事件接收处理的类,或者说是事件发送者和事件接收者。

事件发送者:发送事件的对象

事件接收者:捕获事件并对其作出响应的对象

定义事件就必须先定义委托,用委托定义事件。激发事件的时候调用委托就可以。定义事件时需要使用关键字event,

下面是使用event创建事件:

View Code
1 delegate void MyDelegate(int i, int j);
2 class Program
3 {
4 public event MyDelegate FirstEvent;
5 static void Main(string[] args)
6 {
7 }
8 }

委托与事件示例:

View Code
 1 //派生类TemperatureEventArgs
2   public class TemperatureEventArgs : EventArgs
3 {
4 private int temperature;
5
6 public int Temperature
7 {
8 get { return temperature; }
9 //set { temperature = value; }
10 }
11 public TemperatureEventArgs(int _temperature)
12 {
13 temperature = _temperature;
14 }
15 }
16  //事件触发类
17 public class EventSender
18 {
19 public delegate void TemperatureEventHander(object sender, TemperatureEventArgs e);
20 public event TemperatureEventHander temperaturePress;
21 protected virtual void OnTemperaturePess(TemperatureEventArgs e)
22 {
23 TemperatureEventHander hander = temperaturePress;
24 if (hander != null)
25 {
26 temperaturePress(this, e);
27 }
28 }
29 public void isTemperaturePess(int temperature)
30 {
31 OnTemperaturePess(new TemperatureEventArgs(temperature));
32 }
33    }
34   //事件发生处理类
35 public class EventReceive
36 {
37 public void Press(object sender, TemperatureEventArgs e)
38 {
39 if (e.Temperature > 80)
40 {
41 Console.WriteLine("报警器检测温度为{0},马上会发生火灾,请速撤离现场", e.Temperature);
42 }
43 else if (e.Temperature > 50 && e.Temperature <= 80)
44 {
45 Console.WriteLine("报警器检测温度太高,可能会发生火灾,请做好撤离现场的准备");
46 }
47 else
48 {
49 Console.WriteLine("这里温度正常,请安心工作");
50 }
51 }
52    }
53   //在主程序中调用事件
54 class Program
55 {
56 static void Main(string[] args)
57 {
58 bool trueorfalse = true;
59 while (trueorfalse)
60 {
61 Console.WriteLine("请输入检测器温度,(只能输入数字,否则会出现异常):");
62 int temperature = Convert.ToInt32(Console.ReadLine());
63 EventSender es = new EventSender();
64 EventReceive er = new EventReceive();
65 es.temperaturePress += new EventSender.TemperatureEventHander(er.Press);
66 es.isTemperaturePess(temperature);
67 if (temperature > 200)
68 {
69 trueorfalse = false;
70 }
71 Console.WriteLine("--------------------------------------");
72 Console.WriteLine("--------------------------------------");
73 } Console.WriteLine("================================================================");
74 Console.WriteLine("由于温度太高报警器已经损坏,程序将在5秒后退出程序");
75 Console.WriteLine("请等候......");
76 Console.WriteLine("距系统关闭还有5秒");
77 System.Threading.Thread.Sleep(1000);
78 Console.WriteLine("离系统关闭还有4秒");
79 System.Threading.Thread.Sleep(1000);
80 Console.WriteLine("离系统关闭还有3秒");
81 System.Threading.Thread.Sleep(1000);
82 Console.WriteLine("离系统关闭还有2秒");
83 System.Threading.Thread.Sleep(1000);
84 Console.WriteLine("离系统关闭还有1秒");
85 System.Threading.Thread.Sleep(1000);
86 Console.WriteLine("...");
87 }
88   }

如上加粗部分为对委托与事件的调用,调用后程序会根据不同的温度做出不同的反应。

运行结果如下:

 

posted @ 2012-01-27 22:33  翼灵绝  阅读(252)  评论(0编辑  收藏  举报