zoukankan      html  css  js  c++  java
  • C# note 06——delegate 和 event

    1. Delegate类似于于c++中的函数指针,在C#中定义为一个类

    声明定义时,有些像类:

    delegate int MyDelegate(char c);

    实例化:(注意函数不要加括号,要的不是函数调用,而是函数地址)

    MyDelegate myfuncs = new MyDelegate(MyClass.testFunc);

    MyDelegate myfuncs = MyClass.testFunc;

    不支持无参数的构造函数。

    MyDelegate myfuncs = new MyDelegate();

    将多个同类型函数绑到同一个delegate中,可以将一个函数加多次:

    myfuncs += MyClass.testFunc;

    也可以卸下函数

    myfuncs -= MyClass.testFunc;

    加入的函数会按加入顺序逐个执行。

    private void button1_Click(object sender, EventArgs e)

            {

                MyDelegate mydelegate = new MyDelegate(changeByuttonText);

                mydelegate += changeByuttonText;

                TTT t = new TTT();

                mydelegate(t);

            }

     

            public delegate void MyDelegate(TTT t);

            void changeByuttonText(TTT t)

            {

                t.num += 1;

                myButton.Text = "changed" + (t.num);

            }

     

            public class TTT

            {

                public int num = 1;

            }

    上面程序,每次点击事件触发时,t.num加2,当然这是对于引用传递的变量,如果是值传递的变量做参数,则只会加1

    如果只是声明,而没有赋值如,MyDelegate myfunc;则myfunc不能使用“+=”符号(类似空指针)

    完整代码如下:

    总结

    委托是一个类,它定义了方法的类型,使得可以将方法当作另一个方法的参数来进行传递,这种将方法动态地赋给参数的做法,可以避免在程序中大量使用If-Else(Switch)语句,同时使得程序具有更好的可扩展性。

    2. event 与 delegate的使用

    以窗体程序中的button控件为例:

    a) 新建一个winForm 程序,从工具箱中将一个button移入窗体,这时在Form1.cs程序中多了一个函数。

            private void button1_Click(object sender, EventArgs e)

            {

            }

    在这个函数里可以声明这个button的点击事件。但是.net是怎么调用这个函数的呢?

    b) 选中button1_Click右键【查看所有引用】,其中有一个是来自Form1.Designer.cs的引用,点开发现这句代码

    this.button1.Click += new System.EventHandler(this.button1_Click);

    (注:这句代码在类Form1中的函数private void InitializeComponent()中,在Form1.cs中声明的是public partial class Form1 : Form继承自Form类的Form1类的一部分(partial),它的构造函数中的InitializeComponent() 的定义正是在Form1.Desinger.cs中)

    这句代码的语法很像delegate的“+=”挂接运算。

    c) 选中Click,右键【转到定义】转到命名空间System.Windows.Forms的Control类中,在这里我们发现

    public event EventHandler Click;

    Click正是一个event,是一个delegate(EventHandler),

    d) 在这个类里往下找,有许多与点击事件有关的函数,其中有一个

    protected virtual void OnClick(EventArgs e);

      很可能就是在这一步调用的Click,即我们自己定义的button1_Click()函数。

    e) 为了验证,自己建一个MyButton类,继承Button。重写OnClick函数

    public class MyButton : Button

        {

            public delegate void ClickEventHandler(object sender, EventArgs e);

            public event ClickEventHandler ClickEvent;

     

            protected override void OnClick(EventArgs a){

                if (ClickEvent != null)

                {

                    this.Text = "MyButton:我被单击了 ";

                    ClickEvent(this, null);

                }

            }

        }

    在Form1类中进行修改如下

    public Form1()

    {

                InitializeComponent();

                myButton.Location = new Point(10,10);

                myButton.Size =  new System.Drawing.Size(160,60);

                myButton.Text = "hello";

                this.Controls.Add(myButton);

                myButton.ClickEvent += new MyButton.ClickEventHandler(OnClickEvent);

            }

            void OnClickEvent(object sender,EventArgs e)

            {

                myButton.Text +=("MyForm:我知道你被单击了");

    }

    运行结果如下:

     

    3. event 和 delegate的区别

    a) delegate和类是一个级别的,可以直接写命名空间下,不用寄存在类中;

    event和函数,property是一个级别,必须写在类中。

    b) event 要声明必先要有一个delegate(EventHandler)

    delegate int MyDelegate();

    event MyDelegate MyEvntHandler;

      

  • 相关阅读:
    vim介绍 & vim颜色显示和移动光标& vim一般模式下移动光标 & vim一般模式下复制、剪切和粘贴
    lvm 详解 磁盘故障小案例
    磁盘格式化、磁盘挂载、手动增加swap空间
    df du 磁盘分区
    su sudo 限制root远程登录
    usermod 用户密码管理 mkpasswd
    顺序查找,二分法查找,插值查找算法实现及分析
    完全二叉树的构建及三种遍历
    Mybatis由于类型转换出现的问题
    delimiter解释
  • 原文地址:https://www.cnblogs.com/CsharpNote/p/4443001.html
Copyright © 2011-2022 走看看