.net学习之委托和事件

1.什么是委托
通俗的说:委托就是一个能够存储符合某种格式(方法签名)的方法的指针的容器
上传图片:

2.委托语法
准备一个方法:string Hello(string userName){}
string Hello2(string userName){}
声明委托类:delegate string DGSayHi(string userName);
创建委托对象:DGSayHi dgSay = new DGSayHi(Hello);
或 DGSsyHi dgSay = Hello;
追加方法:dgSay+=Hello2;
删除方法:dgSay -=Hello2;
调用委托:dgSay("你好");

3.多播委托
通常将包含多个方法指针的委托叫做多播委托
其实每个用户定义的委托类型编译后都是一个继承于多播委托的类,看源码:

上传图片:

4.委托的目的
(1)能将方法作为参数和返回值传递
(2)调用一个委托,执行N个方法(多播委托)

5.委托的缺点
不进行控制的缺点:可以使用Click=null来清除所有注册的事件,可以用Click()来假冒事件的触发。
解决方案,把委托成员做成private的,然后增加AddClickEventHandler、RemoveClickEventHandler两个public方法

6.什么是事件
对委托变量的可访问性进行控制封装
语法:public delegate void DGSayHi(string name);
public event DGSayHi dgSay;//创建事件委托(本质还是委托对象)
event会自动生成一个private delegate变量和两个函数: add和remove,C#编译器用这两个方法支持+=和-=操作符

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApplication1
{
    public delegate void DGEach(int index,object item);
    public delegate void DGTest();

    internal class Program
    {
        public static void Test1(DGTest dgTest)
        {
            dgTest(); //编译后:dgTest.Invoke();
            Console.WriteLine("Test1");
        }

        public static void Test2()
        {
            Console.WriteLine("Test2");
        }

        public static void Test3()
        {
            Console.WriteLine("Test3");
        }

        /// <summary>
        /// 委托当返回值
        /// </summary>
        /// <param name="strType"></param>
        /// <returns></returns>
        public static DGTest InvokeTest(string strType)
        {
            switch (strType)
            {
                case "2":
                    return Test2;
                case "3":
                    return Test3;
                default:
                    return Test3;
            }
        }

        /// <summary>
        /// 使用委托模仿jQuery each方法
        /// </summary>
        /// <param name="list"></param>
        /// <param name="func"></param>
        public static void Each(ArrayList list, DGEach func)
        {
            for (int i = 0; i < list.Count; i++)
            {
                func(i, list[i]);
            }
        }

        private static void Main(string[] args)
        {
            #region 委托当参数

            //DGTest dgTest = new DGTest(Test2);//或者    DGTest dgTest  = Test2;
            //Test1(dgTest);

            #endregion

            #region  委托当返回值

            //DGTest dgTest = InvokeTest("2");
            //dgTest();

            #endregion

            #region 完成 Each方法

            //ArrayList list = new ArrayList();
            //list.Add("刘德华");
            //list.Add("张学友");
            //list.Add("郭富城");
            //list.Add("黎明");
            // Each(list, delegate(int index,object item)
            // {
            //     Console.WriteLine(index+"---------"+item.ToString());
            // });

            #endregion

            #region 事件练习,一个设计模式的题目,说有三个对象,猫,老鼠,人,猫看见了老鼠,老鼠吓跑了,在过程中把人吵醒, 在编程过程中注意新的对象的参与
            Cat c = new Cat();
            c.Name = "tom";
            c.DGRunEventHandler += c_DGRunEventHandler;
            c.SeeMouse(c.Name);
            #endregion
        }

        private static void c_DGRunEventHandler(object sender,EventArgs e)
        {
            Mouse m = new Mouse();
            m.Name = "mouse1";
            m.DGRunEventHandler += m_DGRunEventHandler;
            m.MouseRun(m);
        }

        private static void m_DGRunEventHandler(object sender, EventArgs e)
        {
            Person p = new Person();
            p.WakeUp(sender);
        }
    }


        public class Cat
        {
           public event EventHandler DGRunEventHandler;
            public void SeeMouse(string name)
            {
                Console.WriteLine(name+"看见老鼠");
                if (DGRunEventHandler != null)
                {
                    DGRunEventHandler(this,new EventArgs());
                }
            }

            public  string Name { get; set; }
        }
        public class Person
        {
            public void WakeUp(object sender)
            {

                 Console.WriteLine((sender as Mouse).Name+"老鼠跑,人醒了");
            }
            public string Name { get; set; }
        }

        public class Mouse
        {
            public event EventHandler DGRunEventHandler;
            public void MouseRun(object sender)
            {
                Console.WriteLine((sender as Mouse).Name+"老鼠跑");
                if (DGRunEventHandler != null)
                {
                    DGRunEventHandler(this, new EventArgs());
                }
            }
            public string Name { get; set; }
        }
}
原文地址:https://www.cnblogs.com/yxlblogs/p/3833148.html