C#委托事件相关的疑惑,为什么用委托,好处在哪?

最近遇到了一些C#委托相关的问题,貌似理解了,去写的时候又不知为何,所以就去查了些相关文章去了解,下面写下我的理解

       首先什么是委托?菜鸟教程上是这样说的:C# 中的委托(Delegate)类似于 C 或 C++ 中函数的指针。委托(Delegate) 是存有对某个方法的引用的一种引用类型变量。引用可在运行时被改变。

所以说它是引用类型变量,引用类型和指针是不一样的,为什么不一样?百度百科引用类型就知道了。

      还有为什么C#中不用指针了,反而出现了委托呢?大多都是说指针不安全,为什么不安全呢?比如,使用前未初始化.用后未释放,造成内存泄漏,或者调用了一个已经释放不存在的指针,还有越界的问题。委托更安全,它是面向对象的。

当然委托还有别的好处和作用这个只有接触的越多知道的越多了,我粘贴下一句论坛里的一段话以后来体会

没有委托 就没有安全指针用
没有委托 就没有事件用
没有委托 就没有回调用
没有委托 也没有异步调用
没有委托 就没有多个进程
没有委托 就没有windows form
没有委托 那么你也不用学习.net 了
那么你说委托 有什么用?

在使用委托时首先要 定义——>声明——>实例化——>作为参数传递给方法——>使用委托。下面就具体看下如何使用委托的:

定义:delegate  void  Delegatename(type1 para1,type2 para2);

声明:Delegatename  obj;

实例化+传递方法:obj = new Delegatename(someone.Method);

执行委托:Delegatename();

写一个例子更直观的看委托,老师不想自己去收作业了, 就委托课代表去收作业(课代表是老师的眼线所以命名Eyeliner)。

     class Eyeliner
    {
        //被委托的函数
        public static void GetTheHomework()
        {
            Console.WriteLine("我是课代表,我来替老师收作业来了");
        }
    }
    class Teacher
    {
        //定义一个委托
        public delegate void Collecthomework();
        public static void Main()
        {
            //实例化一个委托
            Collecthomework Delegate = new Collecthomework(Eyeliner.GetTheHomework);
            //执行这个委托
            Delegate();
            Console.ReadKey();
        }
    }

当执行到Delegate()的时候就去执行GetTheHomework()了,这就是委托了。

 

 

 

委托通常跟事件联系在一起,所以也来说一下通过事件使用委托的例子

事件在类中声明且生成,且通过使用同一个类或其他类中的委托与事件处理程序关联。包含事件的类用于发布事件。这被称为发布器(publisher)类。其他接受该事件的类被称为订阅器(subscriber)类。事件使用 发布-订阅(publisher-subscriber)模型。

看下面这俩,这俩好像更好理解:

发布器(publisher) 是一个包含事件和委托定义的对象。事件和委托之间的联系也定义在这个对象中。发布器(publisher)类的对象调用这个事件,并通知其他的对象。

订阅器(subscriber) 是一个接受事件并提供事件处理程序的对象。在发布器(publisher)类中的委托调用订阅器(subscriber)类中的方法(事件处理程序)。

同样还是写一个例子好一点吧,一个人不想自己去打官司 ,委托律师帮他打官司。

//发布器类
    public class TheGay
    {
        private int para;
        //定义一个委托
        public delegate void WorkForMe();
        //基于上面的委托定义一个事件
        public event WorkForMe Work;
        public  void Link()
        {
            if (Work != null)
            {
                Work();
            }
            else
            {
                Console.WriteLine("今天不打官司,还没有找到律师");
                Console.ReadKey();//回车继续
            }

        }
        //构造函数
        public TheGay()
        {
            int para = 6;
            GetState(para);

        }
        public void GetState(int a)
        {
            if (para != a)
            {
                para = a;
                Link();
            }

        }
    }
    //订阅器类
    public class Lawyer
    {
        //律师被委托后要做的
        public void DoTheWork()
        {
            Console.WriteLine("律师来了,去打官司");
            Console.ReadKey();//回车继续
        }
    }
    //触发类
    public class MainClass
    {
        public static void Main()
        {
            TheGay gay = new TheGay();//发布器类创建对象
            Lawyer lawyer = new Lawyer();//订阅器类创建对象
            gay.Work += new TheGay.WorkForMe(lawyer.DoTheWork);//关联起来
            gay.GetState(1);//执行
            gay.GetState(2);
        }
    }

执行结果如下

第一句是因为我们刚创建发布器类对象TheGay gay = new TheGay(),这个时候还未关联订阅器类对象,先进入到构造函数中

public TheGay()然后调用了GetState()函数,GetState()又调用了Link(),因为还没有关联(注册)所以进入else,输出这句话。

第二句和第三句因为关联了所以就没有进入else,进入if,执行了Work()因为此时已经关联了lawyer.DoTheWork(),所以就让lawyer.DoTheWork()去做事了,打印出了第二第三句。

因为上面也说了委托是一个引用变量,而引用其实就是对象的一个别名,所以我们大可把

gay.Work += new TheGay.WorkForMe(lawyer.DoTheWork)这一行看做是gay.Work 起个别名,它叫lawyer.DoTheWork

执行lawyer.DoTheWork其实就是在执行gay.Work,当然这也只是我的理解,如果理解偏差还请各位大佬指正。

 

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值