• 委托和事件(无参数事件和有参数事件)


    一、为什么使用委托【引用CSDN】

    (1)在写类的时候,根本就不能确定要调用哪个对象的方法:例如,你把自己的一个对象上的方法挂在微软的textbox 的一个事件上。微软在写textbox时根本就不可能知道这个事件发生时,需要调用哪个对象的哪个方法,只有你自己去指定说需要调什么方法,并且以委托的方式挂在相应的事件上。
    微软在写textbox的事件时,唯一能确定的是这个事件的格式,或者说这个事件需要调用的方法的格式,
    类似于 button1_click(object sender, EnentArgs e) 等等。 只要是按照这个类型写的方法,都能被挂在这个事件上,并且在事件发生时,方法会被调用。这只是基于消息驱动的实现方式之一。

    (2)想象一下如果把你“用嘴吃东西的过程”封装成一个类吧:
    其中对于吃这个动作是这么定义的:
    public void 吃(食物)
    {
      把食物塞你嘴里(); // step 1
      嘴开始有所动作(食物); // step 2
      咽下去(是否可以咽下去); // step 3
    }

    注意步骤二,不同的食物你的嘴会采用不同的方式处理。
    当食物==水,不会咀嚼直接咽
    当食物==肉包子,当然要嚼嚼再咽
    当食物==口香糖,只嚼不咽
    当食物==鱼,你还要仔细的吐出鱼刺......
    显然你不可能在你的类里预见到所有情形,这种情况下就可以把“嘴开始有所动作”考虑定义成委托,让客户端调用时给出具体实现,至于在类里,占个位而已。

    二、实现委托的步骤

    1.定义委托 
    2.定义委托实例
    3.将方法登记到委托实例中
    4.如果委托有登记事件,则执行实例

    举两个个简单的例子:

    //无参数的情况   
     public class Test
        {
            private delegate void CatShoutHandle();
            private event CatShoutHandle CatShout;
    
            public void TestDelegate()
            {
    
                CatShout += new CatShoutHandle(c_CatShout);
                if (CatShout != null)
                {
                    CatShout();
                }
            }
    
            void c_CatShout()
            {
                Console.WriteLine("This is my Test Delagate!");
            }
    
            static void Main()
            {
    
                Test c = new Test();
                c.TestDelegate();
                return;
            }
        }
    

      有参数情况

    //有参数情况
     public class MyParameter:EventArgs
        {
            private string name;
            public MyParameter(string _name)
            {
                this.name = _name;
            }
    
            public string Name
            {
                get { return name; }
                set { name = value; }
            }
        }
    
        public class Test
        {
            private delegate void CatShoutHandle(object sender,MyParameter para);
            private event CatShoutHandle CatShout;
    
            public void TestDelegate()
            {
    
                CatShout += new CatShoutHandle(Test_CatShout);
                MyParameter para = new MyParameter("My test Parameter Name");
                if (CatShout != null)
                {
                    CatShout(this,para);
                }
            }
    
            void Test_CatShout(object sender, MyParameter para)
            {
                Console.WriteLine("This is my Test Delagate! Parameter's name is: {0}",para.Name);
            }
    
        
    
            static void Main()
            {
    
                Test c = new Test();
                c.TestDelegate();
                return;
            }
        }
    

      

     三、下面的例子是一个没有使用事件并含有参数的委托 

     class clsDelegate
        {
            public delegate int simpleDelegate(int a, int b);
            public int addNumber(int a, int b)
            {
                return (a + b);
            }
    
            public int mulNumber(int a, int b)
            {
                return (a * b);
            }
    
            static void Main(string[] args)
            {
                clsDelegate clsDlg = new clsDelegate();
                simpleDelegate addDelegate = new simpleDelegate(clsDlg.addNumber);
                simpleDelegate mulDelegate = new simpleDelegate(clsDlg.mulNumber);
                if (addDelegate != null && mulDelegate != null)
                {
                    int addAns = addDelegate(10, 12);
                    int mulAns = mulDelegate(10, 10);
                    Console.WriteLine("addNum method using a delegate: {0}", addAns);
                    Console.WriteLine("mulNum method using a delegate: {0}", mulAns);
                    Console.Read();
                }
            }
        }
    

     

    四、匿名委托的使用

    匿名委托是使用委托的另一种方式,使用匿名委托时,代码执行的不太快。编译器仍指定了一个方法,该方法只有一个指定的名称。在匿名方法内部不能访问不安全的代码,也不能在匿名方法外部使用ref和out参数。

      //匿名委托
            private delegate void TestDelegate2(int a);
            public void Eample2()
            {
                int a = 12;
                TestDelegate2 t = delegate(int x)
                { 
                    Console.WriteLine("output x : {0}", x); 
                };
                t(a);
            }
    
            static void Main()
            {
    
                Test c = new Test();
                c.Eample2();
                return;
            }
    

      匿名委托示例2,跟上一个示例类似

    class Program  
      {       
       delegate string delegateTest(string str);      
        static void Main(string[] args)  
         {         
             string second = ",second";       
             delegateTest test =  delegate(string para)        
            {             
             para += second;      
                  para += ",third";       
                 return para;         
           };          
          Console.WriteLine( test("first"));
       }
    }
    

      

     五、下面是两个稍微复杂的例子

    1.无参数事件

      class Program
    {

    static void Main(string[] args)
    {
    Cat cat
    = new Cat("small cat");
    Mouse mouse1
    = new Mouse("small mouse1");
    Mouse mouse2
    = new Mouse("small mouse2");

    //将Mouse的run方法通过实例化委托Cat.CatShoutEventHandlerd登记到CatShout中。
    cat.CatShout += new Cat.CatShoutEventHandler(mouse1.Run);
    cat.CatShout
    += new Cat.CatShoutEventHandler(mouse2.Run);

    cat.CatShout
    += new Cat.CatShoutEventHandler(cat_CatShout);


    cat.Shout();
    Console.ReadLine();
    }
    static void cat_CatShout()
    {

    Console.WriteLine(
    "cat is coming ,mouse3 run");
    }

    }

    public class Cat
    {
    //声明委托
    public delegate void CatShoutEventHandler();
    public event CatShoutEventHandler CatShout;
    private string _name;
    public Cat(string name)
    {
    this._name = name;
    }
    public void Shout()
    {
    Console.WriteLine(
    "miao, I am {0}", _name);
    //如果CatShout中有对象登记事件,则执行CatShout()
    if (CatShout != null)
    CatShout();
    }
    }
      
    public class Mouse
    {
    private string _name;
    public Mouse(string name)
    {
    this._name = name;
    }
    public void Run()
    {
    Console.WriteLine(
    "Cat is coming, {0} run", _name);
    }
    }

      

    2.有参数事件

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    namespace weituo
    {
        class Class1
        {
            static void Main(string[] args)
            {
    
                Cat cat = new Cat("small cat");
                Mouse mouse1 = new Mouse("small mouse1");
                Mouse mouse2 = new Mouse("small mouse2");
    
                //将Mouse的run方法通过实例化委托Cat.CatShoutEventHandlerd登记到CatShout中。
                cat.CatShout += new Cat.CatShoutEventHandler(mouse1.Run);
                cat.CatShout += new Cat.CatShoutEventHandler(mouse2.Run);
    
                cat.CatShout += new Cat.CatShoutEventHandler(cat_CatShout);
    
                cat.Shout();
                Console.ReadLine();
            }
    
            static void cat_CatShout(object sender, CatShoutEventArgs e)
            {
                Console.WriteLine("cat is coming ,mouse run");
            }
    
        }
        public class CatShoutEventArgs : EventArgs
        {
            private string _name;
            public CatShoutEventArgs(string name)
            {
                this._name = name;
            }
    
            public string Name
            {
                get { return _name; }
                set { _name = value; }
            }
        }
        public class Cat
        {
    
            //声明委托
            public delegate void CatShoutEventHandler(object sender, CatShoutEventArgs e);
    
            public event CatShoutEventHandler CatShout;
            private string _name;
            public Cat(string name)
            {
                this._name = name;
            }
    
    
            public void Shout()
            {
                Console.WriteLine("miao, I am {0}", _name);
                CatShoutEventArgs e = new CatShoutEventArgs(_name);
                //如果CatShout中有对象登记事件,则执行CatShout()
                if (CatShout != null)
                    CatShout(this, e);
    
            }
    
        }
    
        public class Mouse
        {
            private string _name;
            public Mouse(string name)
            {
                this._name = name;
            }
    
            public void Run(object sender, CatShoutEventArgs args)
            {
                Console.WriteLine("Cat {0} is coming, {1} run", args.Name, _name);
            }
        }
    }
    

      


    3、WPF中的事件

     3.1 public Window1()
            {
                InitializeComponent();
                this.Loaded += new RoutedEventHandler(Init);
            }
            void Init(object sender, RoutedEventArgs e)
            {
                button2.Click += new RoutedEventHandler(button2_Click);
                button3.Click += new RoutedEventHandler(button3Click);
            }
            void button3Click(object sender, RoutedEventArgs e)
            {
                 MessageBox.Show("testbutton3"); 
           }
            void button2_Click(object sender, RoutedEventArgs e)
            {
               MessageBox.Show("testbutton2"); 
            }
    

     3.2DispatcherTimer的使用.  集成到按指定时间间隔和指定优先级处理的 Dispatcher队列中的计时器。

    DispatcherTimer timer = new DispatcherTimer();

    timer.Interval
    = TimeSpan.FromSeconds(1);

    this.Loaded += delegate

    {

      
    //处理函数

      button2_Click();

      timer.Stop();

    };

    timer.Start();


    六、EventHandler泛型委托

        class EventHandlerTest
        {
            public static void TestEventHandler()
            {
                HasEvent has = new HasEvent();
                has.SampleEvent += new EventHandler<MyEventArgs>(has_SampleEvent);
                has.EventTest("work smart!");
                has.EventTest("work hard!");
            }
    
            static void has_SampleEvent(object sender, MyEventArgs e)
            {
                Console.WriteLine(e.Message);
            }
        }
    
        public class MyEventArgs:EventArgs
        {
            private string msg;
    
            public MyEventArgs(string message)
            {
                msg = message;
            }
            public string Message
            {
                get { return msg; }
                set { msg = value; }
            }
        }
    
        public class HasEvent
        {
            public event EventHandler<MyEventArgs> SampleEvent;
    
            public void EventTest(string str)
            {
                EventHandler<MyEventArgs> myEvent = SampleEvent;
                if (myEvent != null)
                {
                    myEvent(this, new MyEventArgs(str));
                }
            }
        }
    

      

      

  • 相关阅读:
    整体的一个学习线路图
    PyCharm快捷键
    iOS从初级至高级开发工程师面试知识点
    第1章 iOS逆向工程简介
    iOS逆向工程分析与实战-开篇
    《牧羊少年奇幻之旅》读书笔记
    《如何高效学习》读书笔记
    函数式编程-RAC学习笔记
    iOS 能实现一键分享多图到朋友圈吗
    VC/MFC动态画线,画圆,画椭圆,画矩形 .
  • 原文地址:https://www.cnblogs.com/linlf03/p/2041657.html
Copyright © 2020-2023  润新知