委托和事件学习总结

原创 2013年12月02日 22:38:28

委托和事件学习总结

         有如下图所示的两个窗体Form1和Form2,点击Form1窗体上的button1按钮,弹出Form2窗体,然后在Form2窗体上点击button1按钮,修改Form1窗体的背景色或是给Form1窗体的TextBox赋值。

    

         按照最普通的想法,需要把Form1窗体对象作为一个变量传递给Form2窗体,并且把TextBox的修饰符改为public,然后在Form2窗体中就可以访问Form1窗体中的TextBox并给它赋值。但这样做存在安全隐患,因为我们可以在Form2窗体中任意改动Form1窗体,一般来说,这是不被允许的。

         学习了面向对象之后,我想,也许可以用接口来实现这一功能。我们定义一个接口,里面有一个未实现的可以改变窗体背景色的方法,然后让Form1窗体实现这个接口。在实现接口的方法中,我们就可以让Form1窗体改变自己的属性。这样在Form2窗体中,我们直接定义一个接口类型的变量,然后调用这个接口所定义的方法就可以达到目的。具体代码如下:        

public interface IChangecolorable
    {
        voidSetColor();
    }
         public partial class Form1 : Form,IChangecolorable
    {
        publicForm1()
        {
            InitializeComponent();
        }
        privatevoid button1_Click(objectsender, EventArgs e)
        {
            Form2f2 = new Form2();
            f2.SetColor = this;
            f2.Show();
        }
        public void SetColor()
        {
            this.BackColor= Color.AliceBlue;
        }
       
    }
         public partial class Form2 : Form
    {
        publicForm2()
        {
            InitializeComponent();
        }
        public IChangecolorable SetColor { get; set; }
        privatevoid button1_Click(objectsender, EventArgs e)
        {
            SetColor.SetColor();
 
            Formf = SetColor as Form1;
            f.Controls.Clear();
 
            SetTxt("金e山¦?打䨰字Á?!ê?");
 
        }
    }

         但是,固然我们可以用接口实现这个功能,但在Form2窗体中,我们仍然可以把接口变量SetColor强转为Form1类型的对象,因为我们在Form1窗体中把Form1对象本身赋值给了SetColor变量,强转后,这个对象仍然是Form1窗体。就算Form1里面的控件都是private类型,我们仍然可以通过窗体的属性Controls来对窗体控件进行操作,因为Controls存储了当前窗体的所有控件。因此这样的做法也不是太好。

         那么,我们是不是可以让外部类仅仅只能访问Form1窗体中改变属性值的方法SetColor,而不允许访问其它任何成员呢?当然可以,这就要用到委托。通过委托,我们可以把改动属性这一动作委托给第三方,在类的外部,我们就可以通过这个委托来访问这个方法来达到目的,但不能访问类内部的其它任何成员。

         委托是一种数据类型,用于存储某种格式的方法。广义上来讲,委托也是一种多态。委托就是将方法或函数当作变量来处理,我们可以给委托类型的变量进行赋值、运算和方法传递等操作。定义委托时,使用delegate关键字。如果没有显式指定访问修饰符,委托的默认访问修饰符为internal。声明委托时,要有返回类型、委托名和参数列表,如果没有参数,参数列表可以为空。如下:

         public delegate void DelegateSetTxt(string text);

       在Form2窗体中,我们可以声明一个委托类型的变量SetTxt作为属性:

       public DelegateSetTxt SetTxt { get;set; }

       然后在显示Form2窗体之前,我们为这个属性赋值:

       Form2f2 = new Form2();

    //f2.SetColor = this;

    f2.SetTxt= SetTxt;

f2.Show();

注意,给委托变量赋值时,这个值只能是方法名,并且方法名后面不能有小括号。而且这个方法的返回类型和参数类型必须和委托一致。否则,就会报错。上面的写法是一个简写方式,原本的写法应该是new一个委托类型的对象,然后把方法名作为一个参数传递进去。如下:f2.SetTxt = new DelegateSetTxt(SetTxt);

在Form2窗体中触发按钮点击事件时,我们直接调用这个委托的Invoke方法就可以。当调用了Invoke方法时,相当于调用了委托变量里存储的方法。

SetTxt.Invoke("金山打字!");

如果这个委托没有参数,那Invoke方法也不必添加参数。我们还可以进一步简写调用委托,直接在委托变量名后面跟参数列表。

SetTxt("金山打字!");

这种在一个类中生成另一个类的对象,又在另一个类中通过某些事件返回调用这个类中的方法,调用完成后又返回另一个类的模式叫做回调函数。

如果赋给委托类型变量的方法是私有的,那我们还可以在外部访问到这个方法吗?肯定是可以的。因为我们不是通过类的对象来调用这个方法,而是通过委托来调用的。把一个方法赋值给委托时,是把这个方法的地址赋值给了委托。所以在外部可以通过委托调用私有方法。

       委托既然是一个类型,那么它也具有其它基本类型或自定义类型所具有的特点。我们同样也可以把一个委托类型的变量当作一个参数进行传递。当调用这样的方法时,我们直接给这个方法传递一个与委托一致的方法的方法名即可。

       当我们给委托赋值时,是把一个方法的地址存入委托中的一个数组中,这个数组可以存储多个方法的地址。因此我们可以为一个委托赋值多个不同的方法,这就是多路广播委托,简称多播委托。在多播委托中,必须先用“=”给委托类型的变量赋一个初始值后,才能用“+=”给该委托类型的变量赋予多个值。多播委托执行存入里面的方法的顺序一般是按照添加顺序来执行的,但这并不是绝对的。

       事件就是行为和动作,它是一种特殊的委托类型的变量。Windows就是一个基于事件的驱动模型。声明事件时,使用event关键字。用event关键字实现事件机制的好处是不可以修改事件已经注册的值,不可以冒充进行事件通知。在C#里面,我们一般不可以自定义事件,但可以自定义控件中模拟事件运行机制。事件本身就是一个多播委托,因此,给一个事件赋值时,需要用“+=”来赋值,如下为Button的Click事件:

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

我们也可以省去newEventHandler这个过程而直接把this.button1_Click方法赋予Click事件。当在一个类里面声明了一个事件时,只能在本类里面触发这个事件。外界只能用“+=”和“-=”为事件注册和注销方法,而不能使用“=”为事件赋值,更不可以主动触发事件。

       事件和委托的区别是什么呢?它们是没有可比性的,事件的本质就是委托,它是委托类型的一个对象。委托所起到的就是一个占位的作用,因为它不知道将来要执行的方法的具体代码,此时可以先用委托类型的变量来代替方法的调用。在实际调用前,需要为委托赋值,否则为null。事件的作用与委托一样,只不过多了些限制,不管我们声明的事件的访问修饰符是公共的还是私有的,在编译之后,它都是private,我们都不能通过赋值的方式访问它,只能为事件注册和注销方法,并且事件只能在类的内部被触发。而委托不同,我们可以在类的外部使用“=”覆盖委托所注册的方法,这存在安全隐患。因此事件也相当于是对委托进行的封装。

 

委托与事件经典总结(带源码)

  • 2008年11月14日 09:41
  • 406KB
  • 下载

C#委托和事件的学习资料

  • 2010年04月27日 17:35
  • 60KB
  • 下载

黑马程序员 委托、方法、事件 总结

1.什么是委托:委托是一种特殊的引用类型,它将方法也作为特殊的对象封装起来,从而将方法作为变量或参数进行传递。 2.定义使用: delegete void DualFunction(double x,...

c#事件和委托的实例学习

  • 2015年09月15日 15:10
  • 93KB
  • 下载

委托与事件总结

委托,描述具有相同 返回值类型和传入参数列表(参数个数及类型) 的一类方法(方法的签名),将方法当作参数传递到另一个方法中,并可以在方法中调用传入方法 事件是对委托的封装,要求满足委托所定义的类型的...

C#学习材料...(委托和事件)

  • 2010年06月16日 16:16
  • 469KB
  • 下载

js中的事件委托总结

1,什么是事件委托:通俗的讲,事件就是onclick,onmouseover,onmouseout,等就是事件,委托呢,就是让别人来做,这个事件本来是加在某些元素上的,然而你却加到别人身上来做,完成这...

C#中的委托与事件详解<个人总结>

委托的三种定义方法 new(典型方法) 匿名类 lamda表达式 事实上,这些方法 using System; using System.Collections.Generic; using Sys...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:委托和事件学习总结
举报原因:
原因补充:

(最多只允许输入30个字)