• 委托、事件 茴字有几种写法


    作用

    可以将方法作为变量

    委托与事件最大的作用其实就是可以让方法(函数)成为一个变量,然后再外部实例化这个类时定义这个方法。但是方法不属于基本类型,不能像定义普通变量一样的去声明它,如我们可以定义一个速度变量

    public int speed{get;set;}

    。但是不能定义一个方法

    public 求距离的方法 GetDistince{get;set;}

    我们需要先定义个委托类型 public delegate void 求距离的方法(DateTime dt);

    然后才可以写      public 求距离的方法 GetDistince;

    这样就很麻烦,微软为了解决这个问题就发明了事件、和预定义了Action<> Func<>等委托。然后为了简化事件的写法。接着发明了 事件.Invoke 等方法。所以现在,我们要想将一个类的方法在实例化时定义,就有很多种写法。

    不用委托的代码

    public static  void main()
    {
         console.write("程序要做的事");  
         console.write("程序要做的事");  
         console.write("程序要做的事");  
         console.write("程序要做的事");  
    }

    封装

    后面我发现其他地方也要用到相同的功能,所以我想封装下,将程序要做的事写在另一个类中。

    public static  void main()
    {
        common.DoSomeThing();
    }
    public class common
    {
       public static void DoSomeThing()
        {
         Console.Write("程序要做的事");  
         Console.Write("程序要做的事");  
         Console.Write("程序要做的事");  
         Console.Write("程序要做的事");  
        }
    } 

    委托解决的问题:方法可变,可能有多个类似的方法

    然后我们发现程序要做的事有部分不一样,所以我们希望由main函数可以设置doSomeThing中执行什么函数。

    我们用到的可能doSomeThing可能有下面两个版本

       public static void DoSomeThing1()
        {
         console.write("程序要做的事");  
         console.write("程序要做的事");  
         console.write("程序要做的事");  
         console.write("程序要做的特殊事情1");  
        }
       public static void DoSomeThing2()
        {
         console.write("程序要做的事");  
         console.write("程序要做的事");  
         console.write("程序要做的事");  
         console.write("程序要做的特殊事情2");  
        }

    使用委托

    这样就很不好看,也不利于扩展,所以可以引入委托,这样我们可以在执行的时候自己选择执行什么特殊方法。

        class Program
        {
            static void Main(string[] args)
            {
                //指定特殊的那段程序执行什么
                common.doSomeThingSpeical += common.DoSomeThingSpeical1;
                common.DoSomeThing();
            }
        }
        public class common
        {
            public delegate void DoSomeThingSpeicaldelegate();
            public static DoSomeThingSpeicaldelegate doSomeThingSpeical;
            public static void DoSomeThing()
            {
                Console.Write("程序要做的事");
                Console.Write("程序要做的事");
                Console.Write("程序要做的事");
                if (doSomeThingSpeical != null)
                {
                    doSomeThingSpeical();
                }
                Console.ReadKey();
            }
            public static void DoSomeThingSpeical1()
            {
                Console.Write("程序要做的独特的事1");
            }
            public static void DoSomeThingSpeical2()
            {
                Console.Write("程序要做的独特的事2");
            }
        }

    如果既不想用DoSomeThingSpeical1也不想用DoSomeThingSpeical2,那么可以在调用的时候自己写一个DoSomeThingSpeical3,然后给common.doSomeThingSpeical赋值。

    class Program
        {
            static void Main(string[] args)
            {
                //指定特殊的那段程序执行什么
                common.doSomeThingSpeical += DoSomeThingSpeical3;
                common.DoSomeThing();
            }
    
            public static void DoSomeThingSpeical3()
            {
                Console.Write("程序要做的独特的事3");
            }
        }

    以上就是委托的基本使用了

    预定义的委托

    可以看到,我们要将方法作为变量时,需要先定义一个委托,很麻烦,所以微软后来为我们预定义了一些委托(Action Func 等),我们不用声明这个委托就可以直接用他们做变量。
     如,上面我们写的:
            public delegate void DoSomeThingSpeicaldelegate();
            public static DoSomeThingSpeicaldelegate doSomeThingSpeical;

    可以直接简化为:
            public static Action doSomeThingSpeical;

    同样这个也可以写成event的形式,事件的实现要稍微复杂一点,这个例子虽然能改成event的形式,但是说明不了event的应用场景,对event我还需要深入学习体会。

    匿名方法

    仔细想了下,我觉得还是要先说说匿名方法

    在上面的例子中,我们Main函数定义委托时,我们不想定义一个方法,再赋值,这时就可以用匿名方法,直接就可以写方法体而不需要申明这个方法。

        class Program
        {
            static void Main(string[] args)
            {
                //指定特殊的那段程序执行什么
                common.doSomeThingSpeical += delegate(){
                Console.Write("程序要做的独特的事3");
                };
                common.DoSomeThing();
            }
    
            //public static void DoSomeThingSpeical3()
            //{
            //    Console.Write("程序要做的独特的事3");
            //}
        }

    事件

     

        class Program
        {
            static void Main(string[] args)
            {
                var Test = new Test();
                void eventHandler(object s, EventArgs e)
                {
                    Console.WriteLine("1");
                }
                void eventHandler2(object s, EventArgs e)
                {
                    Console.WriteLine("2");
                }
                void eventHandler3(object s, EventArgs e)
                {
                    Console.WriteLine("3");
                }
                void eventHandler4(object s, EventArgs e)
                {
                    Console.WriteLine("4");
                }
    
                //添加事件
                Test.A += eventHandler;
                Test.EventHandlers.Add(eventHandler2);
                Test.Actions.Add(eventHandler3);
                Test.B += eventHandler4;
    
                Test.Run();
    
                //移除事件
                Test.A -= eventHandler;
                Test.EventHandlers.Remove(eventHandler2);
                Test.Actions.Remove(eventHandler3);
                Test.B -= eventHandler4;
                Console.ReadKey();
            }
        }
        public class Test
        {
            public List<EventHandler> EventHandlers { get; set; } = new List<EventHandler>();
            public event EventHandler A
            {
                add
                {
                    EventHandlers.Add(value);
                }
                remove
                {
                    EventHandlers.Remove(value);
                }
            }
    
            public List<Action<object, EventArgs>> Actions { get; set; } = new List<Action<object, EventArgs>>();
            public event Action<object, EventArgs> B
            {
                add
                {
                    Actions.Add(value);
                }
                remove
                {
                    Actions.Remove(value);
                }
            }
    
            public void Run()
            {
                EventArgs e = new EventArgs();
                foreach (var eventHandler in EventHandlers)
                {
                    eventHandler.Invoke("Test", e);
                }
    
                foreach (var action in Actions)
                {
                    action.Invoke("Test2", e);
                }
            }
        }
    示例
  • 相关阅读:
    操作系统实验报告-信号量的实现和应用
    操作系统实验报告-系统调用
    操作系统实验报告-熟悉实验环境
    Linux下JDK环境变量配置
    BATMAN.adv系列07 过度泛洪的遏制策略与网络重组
    BATMAN.adv系列06 协议栈结构
    BATMAN.adv系列05 数据结构分析
    BATMAN.adv系列04 TVLV包
    BATMAN.adv系列01:BATMAN.adv IV 概述
    Kudu、Hudi和Delta Lake的比较
  • 原文地址:https://www.cnblogs.com/tanl/p/6536783.html
Copyright © 2020-2023  润新知