初学者一般比较难理解委托和事件,因此在这篇文章中,我少说理论上的东西,写几个实例让大家看看,里面的注释写得很详细,希望对大家有帮助。
首先来看一个入门例子,如果看不懂,建议亲自运行下代码,并自己对代码做做修改,看看修改后的效果,这样便于理解哦。。。
Code
using System;
namespace ConsoleApplication1
{
//首先你必须知道,委托是一种引用类型,封装了对方法的引用,相当于c++中的函数指针。
public delegate int mydelegate(string str);//声明了一个委托
class Program
{
static int print(string meg)//这个方法的签名和返回值类型必须与委托一致
{
Console.WriteLine(meg);
return meg.Length;
}
static void printT(mydelegate prn)
{
prn("你好");
}
static void Main(string[] args)
{
mydelegate prn1 = new mydelegate(print);//创建委托实例,相当于prn1这个委托就代表了print这个方法
string s = "直接调用实例委托";
int n = prn1(s);//直接调用委托实例
printT(prn1);//将委托实例作为参数来传递
Console.WriteLine(n);
//输出结果
//直接调用实例委托
//你好
//8
}
}
}
using System;
namespace ConsoleApplication1
{
//首先你必须知道,委托是一种引用类型,封装了对方法的引用,相当于c++中的函数指针。
public delegate int mydelegate(string str);//声明了一个委托
class Program
{
static int print(string meg)//这个方法的签名和返回值类型必须与委托一致
{
Console.WriteLine(meg);
return meg.Length;
}
static void printT(mydelegate prn)
{
prn("你好");
}
static void Main(string[] args)
{
mydelegate prn1 = new mydelegate(print);//创建委托实例,相当于prn1这个委托就代表了print这个方法
string s = "直接调用实例委托";
int n = prn1(s);//直接调用委托实例
printT(prn1);//将委托实例作为参数来传递
Console.WriteLine(n);
//输出结果
//直接调用实例委托
//你好
//8
}
}
}
下面来看看什么是委托链
Code
using System;
namespace ConsoleApplication1
{
public delegate void mydelegate(string str);//声明了一个委托
class Program
{
static void print1(string meg)
{
Console.WriteLine(meg + "1");
}
static void print2(string meg)
{
Console.WriteLine(meg + "2");
}
static void print3(string meg)
{
Console.WriteLine(meg + "3");
}
static void Main(string[] args)
{
//委托中用+或+=来组合委托,用-或-=来移除一个委托。
mydelegate prn1 = new mydelegate(print1);
mydelegate prn2 = new mydelegate(print2);
mydelegate prn3 = new mydelegate(print3);
string s = "委托链";
Console.WriteLine("========分割线========");
prn1(s);
Console.WriteLine("========分割线========");
prn2(s);
Console.WriteLine("========分割线========");
prn3(s);
mydelegate prn = prn1 + prn2;
Console.WriteLine("========分割线========");
prn(s);
prn += prn3;
Console.WriteLine("========分割线========");
prn(s);
prn = prn - prn2;
Console.WriteLine("========分割线========");
prn(s);
prn -= prn1;
Console.WriteLine("========分割线========");
prn(s);
//输出结果
//========分割线========
//委托链1
//========分割线========
//委托链2
//========分割线========
//委托链3
//========分割线========
//委托链1
//委托链2
//========分割线========
//委托链1
//委托链2
//委托链3
//========分割线========
//委托链1
//委托链3
//========分割线========
//委托链3
}
}
}
using System;
namespace ConsoleApplication1
{
public delegate void mydelegate(string str);//声明了一个委托
class Program
{
static void print1(string meg)
{
Console.WriteLine(meg + "1");
}
static void print2(string meg)
{
Console.WriteLine(meg + "2");
}
static void print3(string meg)
{
Console.WriteLine(meg + "3");
}
static void Main(string[] args)
{
//委托中用+或+=来组合委托,用-或-=来移除一个委托。
mydelegate prn1 = new mydelegate(print1);
mydelegate prn2 = new mydelegate(print2);
mydelegate prn3 = new mydelegate(print3);
string s = "委托链";
Console.WriteLine("========分割线========");
prn1(s);
Console.WriteLine("========分割线========");
prn2(s);
Console.WriteLine("========分割线========");
prn3(s);
mydelegate prn = prn1 + prn2;
Console.WriteLine("========分割线========");
prn(s);
prn += prn3;
Console.WriteLine("========分割线========");
prn(s);
prn = prn - prn2;
Console.WriteLine("========分割线========");
prn(s);
prn -= prn1;
Console.WriteLine("========分割线========");
prn(s);
//输出结果
//========分割线========
//委托链1
//========分割线========
//委托链2
//========分割线========
//委托链3
//========分割线========
//委托链1
//委托链2
//========分割线========
//委托链1
//委托链2
//委托链3
//========分割线========
//委托链1
//委托链3
//========分割线========
//委托链3
}
}
}
什么是匿名方法,如何用匿名方法来创建委托实例呢?请看下面这个例子
Code
using System;
namespace ConsoleApplication1
{
//前面我们创建委托实例的时候都指定了方法名称,我们也可以用“内联”的方式将代码块“绑定”到委托实例上,只需要使用delegate。
public delegate void mydelegate1(string str);//声明了一个无返回值的委托
public delegate int mydelegate2(string str);//声明了一个有返回值的委托
class Program
{
static void Main(string[] args)
{
mydelegate1 p1 = delegate(string str1) { Console.WriteLine(str1); };
p1("我是没返回值的");
mydelegate2 p2 = delegate(string str1) { Console.WriteLine(str1); return str1.Length; };
int n = p2("我是有返回值的");
Console.WriteLine(n);
//输出结果
//我是没返回值的
//我是有返回值的
//7
}
}
}
using System;
namespace ConsoleApplication1
{
//前面我们创建委托实例的时候都指定了方法名称,我们也可以用“内联”的方式将代码块“绑定”到委托实例上,只需要使用delegate。
public delegate void mydelegate1(string str);//声明了一个无返回值的委托
public delegate int mydelegate2(string str);//声明了一个有返回值的委托
class Program
{
static void Main(string[] args)
{
mydelegate1 p1 = delegate(string str1) { Console.WriteLine(str1); };
p1("我是没返回值的");
mydelegate2 p2 = delegate(string str1) { Console.WriteLine(str1); return str1.Length; };
int n = p2("我是有返回值的");
Console.WriteLine(n);
//输出结果
//我是没返回值的
//我是有返回值的
//7
}
}
}
到此委托你应该搞明白了吧,如果还不明白,那就动动手指,再搜索点其他资料看看。
接着我们来了解下事件
Code
1 using System;
2 //事件功能由三个互相联系的元素提供的,1.提供事件数据的类,2.事件委托,3.引发事件的类
3 namespace ConsoleApplication1
4 {
5 //发布事件的类
6 public class myEventSource//3.引发事件的类
7 {
8 public class myEventArgs : EventArgs //1.提供事件数据的类,来至System.EventArgs
9 {
10 public readonly char KeyToRaiseEvent; //添加了一个只读属性KeyToRaiseEvent
11 public myEventArgs(char keyToRaiseEvent)
12 {
13 KeyToRaiseEvent = keyToRaiseEvent;
14 }
15 }
16 public delegate void myEventHandler(object sender, myEventArgs e);//2.事件委托
17 public event myEventHandler myEvent;//声明一个事件
18
19 public void OnmyEvent(char keyToRaiseEvent)//引发事件的方法
20 {
21 myEventArgs e = new myEventArgs(keyToRaiseEvent);
22 if (myEvent != null)
23 myEvent(this, e);
24 }
25 }
26 //监听事件的类
27 public class myEventListener
28 {
29 public void KeyPressed(object sender, myEventSource.myEventArgs e)//处理事件的方法,这个方法必须与委托的签名一致
30 {
31 Console.WriteLine("发送者为:{0},所按的键为:{1}", sender, e.KeyToRaiseEvent);
32 }
33 //订阅事件
34 public void Subsribe(myEventSource eventSource)
35 {
36 eventSource.myEvent += new myEventSource.myEventHandler(KeyPressed);//学习了前面的委托就应该明白,这里是把KeyPressed这个方法“绑定”到委托上,然后再通过+=将该委托添加到源对象的事件中。
37 }
38 //取消订阅事件
39 public void UnSubsribe(myEventSource eventSource)
40 {
41 eventSource.myEvent -= new myEventSource.myEventHandler(KeyPressed);
42 }
43 }
44 class Program
45 {
46 static void Main(string[] args)
47 {
48 myEventSource es = new myEventSource();
49 myEventListener el = new myEventListener();
50
51 el.Subsribe(es);//订阅事件,跳到34行看
52 string s = Console.ReadLine();//读入一个字符
53 es.OnmyEvent(s.ToCharArray()[0]);//引发事件,跳到19行看
54
55 el.UnSubsribe(es);
56 s = Console.ReadLine();
57 es.OnmyEvent(s.ToCharArray()[0]);
58 //运行结果
59 //a
60 //发送者为:ConsoleApplication1.myEventSource,所按的键为:a
61 //a
62 }
63 }
64 }
65
1 using System;
2 //事件功能由三个互相联系的元素提供的,1.提供事件数据的类,2.事件委托,3.引发事件的类
3 namespace ConsoleApplication1
4 {
5 //发布事件的类
6 public class myEventSource//3.引发事件的类
7 {
8 public class myEventArgs : EventArgs //1.提供事件数据的类,来至System.EventArgs
9 {
10 public readonly char KeyToRaiseEvent; //添加了一个只读属性KeyToRaiseEvent
11 public myEventArgs(char keyToRaiseEvent)
12 {
13 KeyToRaiseEvent = keyToRaiseEvent;
14 }
15 }
16 public delegate void myEventHandler(object sender, myEventArgs e);//2.事件委托
17 public event myEventHandler myEvent;//声明一个事件
18
19 public void OnmyEvent(char keyToRaiseEvent)//引发事件的方法
20 {
21 myEventArgs e = new myEventArgs(keyToRaiseEvent);
22 if (myEvent != null)
23 myEvent(this, e);
24 }
25 }
26 //监听事件的类
27 public class myEventListener
28 {
29 public void KeyPressed(object sender, myEventSource.myEventArgs e)//处理事件的方法,这个方法必须与委托的签名一致
30 {
31 Console.WriteLine("发送者为:{0},所按的键为:{1}", sender, e.KeyToRaiseEvent);
32 }
33 //订阅事件
34 public void Subsribe(myEventSource eventSource)
35 {
36 eventSource.myEvent += new myEventSource.myEventHandler(KeyPressed);//学习了前面的委托就应该明白,这里是把KeyPressed这个方法“绑定”到委托上,然后再通过+=将该委托添加到源对象的事件中。
37 }
38 //取消订阅事件
39 public void UnSubsribe(myEventSource eventSource)
40 {
41 eventSource.myEvent -= new myEventSource.myEventHandler(KeyPressed);
42 }
43 }
44 class Program
45 {
46 static void Main(string[] args)
47 {
48 myEventSource es = new myEventSource();
49 myEventListener el = new myEventListener();
50
51 el.Subsribe(es);//订阅事件,跳到34行看
52 string s = Console.ReadLine();//读入一个字符
53 es.OnmyEvent(s.ToCharArray()[0]);//引发事件,跳到19行看
54
55 el.UnSubsribe(es);
56 s = Console.ReadLine();
57 es.OnmyEvent(s.ToCharArray()[0]);
58 //运行结果
59 //a
60 //发送者为:ConsoleApplication1.myEventSource,所按的键为:a
61 //a
62 }
63 }
64 }
65
希望这几个小例子对大家有帮助!