c# 用实例来理解委托与事件

初学者一般比较难理解委托和事件,因此在这篇文章中,我少说理论上的东西,写几个实例让大家看看,里面的注释写得很详细,希望对大家有帮助。

首先来看一个入门例子,如果看不懂,建议亲自运行下代码,并自己对代码做做修改,看看修改后的效果,这样便于理解哦。。。

ContractedBlock.gif ExpandedBlockStart.gif 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
        }
    }
}

 

下面来看看什么是委托链

 

ContractedBlock.gif ExpandedBlockStart.gif 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
        }
    }
}

 

什么是匿名方法,如何用匿名方法来创建委托实例呢?请看下面这个例子

 

 

ContractedBlock.gif ExpandedBlockStart.gif 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
        }
    }
}

 

到此委托你应该搞明白了吧,如果还不明白,那就动动手指,再搜索点其他资料看看。

接着我们来了解下事件

 

 

ContractedBlock.gif ExpandedBlockStart.gif 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 

 

希望这几个小例子对大家有帮助!

转载于:https://www.cnblogs.com/spku400/archive/2009/06/11/1501613.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值