• c# 工厂模式 ,委托 ,事件。


    有些时间 不用 c#了 ,想 写 委托 和 事件 又会 卡下 ,之前也没认真总结过。干脆 做个小结 。

    什么是委托:狭义,不安全函数的指针。不安全在哪里: 任何地方都可以调用委托对象。(实际上委托对象才是函数的指针,而delegate只是一个语法

    什么是事件:狭义,安全的函数指针,安全在哪里:只允许包含事件的类,的内部调用。

    联系和区别:

    delegate关键字类比于class关键字, 定义的是一种委托类型,需要再创建委托对象.

    用event关键字来修饰创建委托对象行为,那么就成了一个特殊的委托对象,就是事件 。

    所以delegate是类,event是修饰语,好比private.

    光板 delegate对象,可以到处调用它。event 修饰的delegate对象,只能在  “event 修饰的delegate对象” 所属类中使用。

    还有一点语法糖,event只允许+=,而不支持=.因为=,可能会在你需要添加的时候,写成=,会覆盖掉之间的方法。

    写完,终于感觉好点了。 

    委托 :

    1.概念:个人 理解 ,加强版的 函数指针,可以存放多个函数 指针 ,算是函数指针集合。但是提供了异步的高级特性(另开一个线程去调用这个函数指针)

    2。 用途:需要对某个方法进行多态或延迟执行的情况下。表现在某个固定模块,先写好函数意图,实现由模块外定义和修改。而固定模块不修改代码。

                     但会导致同样满足要求的工厂模式乱入,区分,工厂模式是在对象级别的延迟和多态。而委托是方法级别的延迟和多态。

    3.常用用法举例:处理消息模块(固定模块),模块编写处理流程。具体哪个方法处理或哪几个方法处理 ,由外部定义实现 。

    4.缺点:委托无限制,可以直接在任何地方,使用委托对象,进行调用。而事件,限制在包含事件的类内部。

    4.简介使用:一个类A里面定义delegate,并定义delegate对象,那么类A的方法FUNB就可以把delegate对象当作函数一样调用。

                        主函数 给 类A的对象中的delegate对象,附加上和delegate原型相同的函数名FUNC。那么主函数,就可以调用A的方法FUNB。 而最终是调用附加上的FUNC方法。

    class KernelModule//固定模块,内部成员必须要有委托(函数指针),来表达意图,而实现来自于外部。
        {
            public delegate string PMSGHandle(string msg);//需要一个函数指针
            public PMSGHandle impHandle;//函数指针对象
            public void ProcessMsg(string msg)
            {
            //一些流程

            if (impHandle != null)
            {

                  //impHandle(msg);//调用函数指针来调用模块外方法。
                  impHandle.BeginInvoke(msg, callbacka, "info");//特性,提供异步调用,并提供回调函数。我去。c#真是逆了天了。使用起来真方便。
           }
    } public void callbacka(System.IAsyncResult iar) { //获取绑定函数的引用 AsyncResult ar = (AsyncResult)iar; PMSGHandle delBp = (PMSGHandle)ar.AsyncDelegate; //等待函数执行完毕 string result = delBp.EndInvoke(iar); Console.Write("callback ret:"+ result); } } class Program { static string pmsg(string msg)//意图的实现1 { Console.Write("process fun1:" + msg + Environment.NewLine); return "pmsg do it"; } static string pmsg2(string msg)//意图的实现2 { Console.Write("process fun2:" + msg + Environment.NewLine); return "pmsg2 do it"; } static void Main(string[] args) { string recvMsg = "0101"; KernelModule myKernel = new KernelModule();//创建模块对象。 myKernel.impHandle = pmsg2;//给模块的委托赋值(把函数指针传递)。 //myKernel.impHandle += pmsg;//委托的特性,可以多路委托。(异步调用只能由一个委托对象) myKernel.ProcessMsg(recvMsg);//调用模块对象的方法。
                // myKernel.impHandle(recvMsg);//编译 通过,对于大多数面向对象设计框架下情况下。非常危险。因为委托一般是在类内部,调用的。
                Thread.Sleep(2000); } }

     2.事件

            概念:对委托的实例化提供了一些限制的一种语法 。public event PMSGHandle impHandle    public  PMSGHandle impHandle 。2个语句。都是生产委托对象。但是加了event后。这个对象进行了一些安全操作限制。

            用途:跟委托一样。

       小结:外部调用事件,会有编译错误。KernelModule.impHandle”只能出现在 += 或 -= 的左边(从类型“KernelModule”中使用时除外) 

      举例:

    class KernelModule//固定模块,内部成员必须要有委托(函数指针),来表达意图,而实现来自于外部。
        {
            public delegate string PMSGHandle(string msg);//需要一个函数指针
            public event PMSGHandle impHandle;//多写一个event关键字。生成一个event对象,而不是一个delegate对象。
            //public PMSGHandle impHandle;//函数指针对象
            public void ProcessMsg(string msg)
            {
           if (impHandle != null)
            {   impHandle(msg);
    //调用函数指针来调用模块外方法。   //impHandle.BeginInvoke(msg, callbacka, "info");//特性,提供异步调用,并提供回调函数。我去。c#真是逆了天了。使用起来真方便。
            }
    } public void callbacka(System.IAsyncResult iar) { //获取绑定函数的引用 AsyncResult ar = (AsyncResult)iar; PMSGHandle delBp = (PMSGHandle)ar.AsyncDelegate; //等待函数执行完毕 string result = delBp.EndInvoke(iar); Console.Write("callback ret:"+ result); } } class Program { static string pmsg(string msg)//意图的实现1 { Console.Write("process fun1:" + msg + Environment.NewLine); return "pmsg do it"; } static string pmsg2(string msg)//意图的实现2 { Console.Write("process fun2:" + msg + Environment.NewLine); return "pmsg2 do it"; } static void Main(string[] args) { string recvMsg = "0101"; KernelModule myKernel = new KernelModule();//创建模块对象。 myKernel.impHandle += pmsg2;//给模块的事件handle添加event,不能再使用=号了(把函数指针传递)。 myKernel.impHandle += pmsg;//委托的特性,可以多路委托。(异步调用只能由一个委托对象) myKernel.ProcessMsg(recvMsg);//调用模块对象的方法。
          myKernel.impHandle(recvMsg);//编译错误 KernelModule.impHandle”只能出现在 += 或 -= 的左边(从类型“KernelModule”中使用时除外)  Thread.Sleep(2000); } }
  • 相关阅读:
    微擎签名出错 invalid signature
    微擎 pdo_fetchall() 函数
    Qt 文本文件的读写操作
    Qt Qlistwidget、Qlistview
    Qt保留小数点后一位、两位……
    Excel怎么快速删除全部空行
    光学镜头参数详解(EFL、TTL、BFL、FFL、FBL/FFL、FOV、F/NO、RI、MTF、TV-Line、Flare/Ghost)
    Image J 介绍
    C# MODBUS协议上位机程序
    C/C++ memmove与memcpy的区别及实现
  • 原文地址:https://www.cnblogs.com/lsfv/p/7905366.html
Copyright © 2020-2023  润新知