C#委托、事件本质(张三对李四)

冲着C#委托+事件来做的一个Demo。里面用代码阐述了事件和委托间的关系。又利用OOP继承机制的多态,编写了这样一个简单控制台程序,并以张三、李四为对象,形成对话。在相应时机触发相应事件。一起来看看吧。
 
标签: <无>
 

代码片段(7)[全屏查看所有代码]

1. [代码]【人】抽象类     

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
/******************************************************************************************************************
 *
 *
 * 说 明:抽象类 -人(版本:Version1.0.0)
 * 作 者:李朝强
 * 日 期:2015/05/19
 * 修 改:
 * 参 考:http://my.oschina.net/lichaoqiang/
 * 备 注:暂无...
 *
 *
 * ***************************************************************************************************************/
namespace Lcq.Event
{
    public abstract class Person
    {
        /// <summary>
        /// 构造函数
        /// </summary>
        public Person()
        {
 
        }
 
 
        #region event
 
        /// <summary>
        /// 说话事件
        /// </summary>
        private _ActionHandler _OnSayHandler = null;
        public event _ActionHandler OnSay
        {
            add { _OnSayHandler += value; }
            remove { _OnSayHandler -= value; }
        }
 
 
        /// <summary>
        /// 走路事件
        /// </summary>
        private _ActionHandler _OnRunHandler = null;
        public event _ActionHandler OnRun
        {
            add { _OnRunHandler += value; }
            remove { _OnRunHandler -= value; }
        }
 
        /// <summary>
        /// 听事件
        /// </summary>
        private _ListenHandler _OnListenHandler = null;
        public event _ListenHandler OnListen
        {
            add { _OnListenHandler += value; }
            remove { _OnListenHandler -= value; }
        }
 
 
        /// <summary>
        /// 虚方法:说话
        /// </summary>
        /// <param name="e"></param>
        protected virtual void Say(PersonEventArg e)
        {
            //说话时,如果存在事件委托,则触发事件委托
            if (_OnSayHandler != null)
            {
                _OnSayHandler(this, e);
            }
        }
 
        /// <summary>
        /// 虚方法:走路
        /// </summary>
        /// <param name="e"></param>
        protected virtual void Run(PersonEventArg e)
        {
            if (_OnRunHandler != null) { _OnRunHandler(this, e); }
        }
 
        /// <summary>
        /// 虚方法:听
        /// </summary>
        /// <param name="e"></param>
        public virtual void Listen(ListenEventArg e)
        {
            if (_OnListenHandler != null) { _OnListenHandler(this, e); }
        }
        #endregion
 
        #region Member
        /// <summary>
        /// 姓名
        /// </summary>
        public string Name { get; protected set; }
 
        /// <summary>
        /// 性别
        /// </summary>
        public string Sex { get; protected set; }
        #endregion
    }
}

2. [代码]派生类:奋斗不息的程序员     

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
/******************************************************************************************************************
 *
 *
 * 说 明: 程序员(版本:Version1.0.0)
 * 作 者:李朝强
 * 日 期:2015/05/19
 * 修 改:
 * 参 考:http://my.oschina.net/lichaoqiang/
 * 备 注:暂无...
 *
 *
 * ***************************************************************************************************************/
namespace Lcq.Event
{
    public class Programmer : Person
    {
 
        /// <summary>
        /// 构造函数
        /// </summary>
        public Programmer()
        {
            //给事件绑定委托函数
            OnSay += new _ActionHandler(Programer_OnSay);
            OnRun += new _ActionHandler(Programer_OnRun);
            OnListen += new _ListenHandler(Programer_OnListen);
        }
 
 
        /// <summary>
        /// 构造函数重载
        /// </summary>
        /// <param name="_Name"></param>
        /// <param name="_Sex"></param>
        public Programmer(string _Name, string _Sex)
            : this()
        {
            //成员初始化
            Name = _Name;
            Sex = _Sex;
        }
 
        /// <summary>
        /// 讨论行为,触发OnSay事件
        /// </summary>
        public void Talk(string sayWords, List<Person> listenPersons)
        {
            //事件参数,构造函数传参,注入
            PersonEventArg e = new PersonEventArg(sayWords, listenPersons);
            base.Say(e);
        }
 
        /// <summary>
        /// 说话事件
        /// </summary>
        /// <param name="programmer"></param>
        /// <param name="e"></param>
        protected void Programer_OnSay(object programmer, PersonEventArg e)
        {
            Console.WriteLine(string.Format("【{0}】说:{1}", Name, e.SayWords));
            for (int i = 0; e.ListenPersons != null && i < e.ListenPersons.Count; i++)
            {
                //事件参数
                ListenEventArg listenArg = new ListenEventArg(e.SayWords, (Programmer)programmer);
 
                //触发了听事件
                e.ListenPersons[i].Listen(listenArg);
            }
        }
 
        /// <summary>
        /// 走路事件
        /// </summary>
        /// <param name="programmer"></param>
        /// <param name="e"></param>
        protected void Programer_OnRun(object programmer, PersonEventArg e)
        {
            Console.WriteLine(string.Format("【{0}】行走...", Name));
        }
 
        /// <summary>
        /// 听事件
        /// </summary>
        /// <param name="programmer"></param>
        /// <param name="e"></param>
        protected void Programer_OnListen(object programmer, ListenEventArg e)
        {
            Console.WriteLine(string.Format("【{0}】听见{1}说:{2}", Name, e.SayPerson.Name, e.ListenWords));
            Console.WriteLine("____________________________________________________________________________");
        }
    }
}

3. [代码]定义行为委托     

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
/******************************************************************************************************************
 *
 *
 * 说 明: 委托(版本:Version1.0.0)
 * 作 者:李朝强
 * 日 期:2015/05/19
 * 修 改:
 * 参 考:http://my.oschina.net/lichaoqiang/
 * 备 注:暂无...
 *
 *
 * ***************************************************************************************************************/
namespace Lcq.Event
{
    /// <summary>
    /// 委托
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    public delegate void _InitHandler(object sender, EventArgs e);
 
    /// <summary>
    /// 委托
    /// </summary>
    /// <param name="person"></param>
    /// <param name="e"></param>
    public delegate void _ActionHandler(object person, PersonEventArg e);
 
 
    /// <summary>
    /// 听事件委托
    /// </summary>
    /// <param name="person"></param>
    /// <param name="e"></param>
    public delegate void _ListenHandler(object person, ListenEventArg e);
}

4. [代码]定义行为事件参数     

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
/******************************************************************************************************************
 *
 *
 * 说 明: 自定义事件参数(版本:Version1.0.0)
 * 作 者:李朝强
 * 日 期:2015/05/19
 * 修 改:
 * 参 考:http://my.oschina.net/lichaoqiang/
 * 备 注:暂无...
 *
 *
 * ***************************************************************************************************************/
namespace Lcq.Event
{
    public class PersonEventArg : EventArgs
    {
        /// <summary>
        /// 构造函数
        /// </summary>
        public PersonEventArg() { }
 
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="sayWords"></param>
        public PersonEventArg(string sayWords, List<Person> listPerson)
        {
            SayWords = sayWords;
            ListenPersons = listPerson;
        }
 
        /// <summary>
        /// 说的话
        /// </summary>
        public string SayWords { get; set; }
 
        /// <summary>
        /// 听客
        /// </summary>
        public List<Person> ListenPersons { get; set; }
    }
}

5. [代码]定义听事件参数     

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
/******************************************************************************************************************
 *
 *
 * 说 明: 听事件参数(版本:Version1.0.0)
 * 作 者:李朝强
 * 日 期:2015/05/19
 * 修 改:
 * 参 考:http://my.oschina.net/lichaoqiang/
 * 备 注:暂无...
 *
 *
 * ***************************************************************************************************************/
namespace Lcq.Event
{
    public class ListenEventArg : EventArgs
    {
 
        /// <summary>
        /// 听到的内容
        /// </summary>
        public string ListenWords { get; set; }
 
        /// <summary>
        /// 说话人
        /// </summary>
        public Person SayPerson { get; set; }
 
        /// <summary>
        /// 构造函数
        /// </summary>
        public ListenEventArg(string listenWords, Person sayPerson)
        {
            ListenWords = listenWords;
            SayPerson = sayPerson;
        }
    }
}

6. [代码]控制台演示Demo     

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
using Lcq.Event;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
/******************************************************************************************************************
 *
 *
 * 说 明: 事件+委托(版本:Version1.0.0)
 * 作 者:李朝强
 * 日 期:2015/05/19
 * 修 改:
 * 参 考:http://my.oschina.net/lichaoqiang/
 * 备 注:暂无...
 *
 *
 * ***************************************************************************************************************/
namespace lcq.IIS
{
    class Program
    {
        /// <summary>
        /// 主程序
        /// </summary>
        /// <param name="args"></param>
        static void Main(string[] args)
        {
 
            //实例化一个程序员对象,张三
            Lcq.Event.Programmer peZS = new Lcq.Event.Programmer("张三", "男");
            peZS.OnListen += new _ListenHandler(张三_OnListen);
 
            //听者
            List<Lcq.Event.Person> listen = new List<Lcq.Event.Person>();
            Lcq.Event.Programmer peLS = new Lcq.Event.Programmer("李四", "男");
 
            //给听事件绑定委托
            peLS.OnListen += new Lcq.Event._ListenHandler(李四_OnListen);
 
            listen.Add(peLS);
 
            peZS.Talk("委托的实质是什么?", listen);
 
            Console.Read();
        }
 
        /// <summary>
        ///李四 听事件
        /// </summary>
        /// <param name="person"></param>
        /// <param name="e"></param>
        public static void 李四_OnListen(object person, Lcq.Event.ListenEventArg e)
        {
            //听见后,回应
            Programmer peLS = (Programmer)person;//李四
 
            //让张三听见
            List<Person> listenPerson = new List<Person>();
            listenPerson.Add(e.SayPerson);
 
            peLS.Talk("委托类似C++里面的指针,但它是类型安全的。", listenPerson);
        }
 
        /// <summary>
        ///张三 听事件
        /// </summary>
        /// <param name="person"></param>
        /// <param name="e"></param>
        public static void 张三_OnListen(object person, Lcq.Event.ListenEventArg e)
        {
            //听见后,回应
            Programmer peZS = (Programmer)person;//张三
 
            //结束讨论
            peZS.Talk("嗯,说的很对。", null);
        }
    }
}

7. [图片] 控制台Demo.png    

posted @ 2016-10-02 21:25  天涯海角路  阅读(203)  评论(0)    收藏  举报