C# note 06——delegate 和 event
2015-04-20 23:11 yinglang 阅读(146) 评论(0) 编辑 收藏 举报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:我被单击了\n";
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;