C#中委托和事件 最近学习C#的委托和事件,感觉委托和事件功能很像,都是类似C/C++中的函数指针,这里不过是指向方法的。可是有了委托干嘛还要弄事件,他们的具体区别是什么,各有什么好处! 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 委托、事件在以后的程序开发中肯定会经常使用的,给你推荐一个地址,个人觉得讲的很好。认真看了 我觉得你就基本理解了。http://www.tracefact.net/CSharp-Programming/Delegates-and-Events-in-CSharp.aspx 从技术角度说,当你声明如下的事件时:public event EventHandler Click;编译器会为你生成一些代码,差不多象这样:private EventHandler _click;public event EventHandler Click{ add { _click += value; } remove { _click -= value; }}这就是说,事件成员本质上是方法。那么,我直接使用公有的委托类型的字段不是更直接么:public EventHandler Click;这么写也是可以的,但是这个代码不能用在接口里,因为接口不允许定义字段。当你想为接口定义事件而不能时,会不会觉得它是个很蹩脚的东西?以上只是从技术角度解释,我更愿意从委托和事件的含义上理解他们的差别。委托是个很技术化的词语,而事件是个更直观的概念。委托是干什么用的,无非是封装个方法而已。如果一个类公开了 Click 委托字段,我会把它理解成“这是点击按钮时会调用的回调方法”,也许还会纠结一下这个字段是不是叫做 ClickCallback 更准确一点,而当它是一个 event 时,它表达的就是“这是点击按钮时引发的事件”,这让我可以更直观的思考,让一堆乱麻似的思维得到一点休息 事件是面向外部的,可以在外部进行事件的绑定和移除,委托在内部进行调用。你也可以直接在外部赋值一个函数为委托所使用。但是+=和-=是一种内部通知外部的手段,外部可以再内部发生变化时候进行一定的操作,便捷。。AA a=new AA();a+=new handler(test);void test(object sender,eventargs e)当然+=和-=看起来更具有美感 很多人不动脑子鹦鹉学舌地不断引用“委托类似C/C++中的函数指针”,但是事实上他们对C/C++中的函数指针能用来干什么并不清楚,或许他们在学校学习的那一点浅薄的C语言知识根本从来没有用过一次“函数指针”。用一个更不理解的概念解释一个不理解的概念,这不是扯淡吗?况且委托多大程度上类似C/C++中的函数指针还是一个问题,其实委托一点也不类似函数指针,恰恰相反,它类似一个抽象基类。什么是委托?我想搞清楚这个问题必须用你理解的概念去理解。首先回忆下你是怎么理解什么是函数的。我想恐怕没有人教你函数就是汇编语言里面的将数据放入堆栈再跳转的宏(invoke宏)吧。肯定老师会告诉你,函数就是给定一个自变量,通过计算得到另一个变量,产生的变量映射关系。那么程序设计语言上的函数就是一段程序,对输入的参数进行处理,再输出结果。如果你明白了函数,那么什么是委托?同样,你不需要理解什么“委托类似C/C++中的函数指针”,只有不合格的蹩脚老师才会灌输这个似是而非而且毫无用处的结论。你只要明白,委托的作用就是代表一种函数类型,使得我们可以将函数作为数据传给一个高阶函数。也就是一个函数可以接受另一个函数作为它的自变量,求值。我们看一个数学上的例子。比如说我们求一个函数的定积分。我们可以写出如下表达式:f积分(f原函数,上限,下限),这里,f原函数就是一个自变量,同时是一个函数。而f积分这个函数就是一个高阶函数。委托的作用就是,代表一种函数类型,我们可以这么定义这个函数:double f积分(OrgFunctionDelegate func, double low, double high);delegate double OrgFunctionDelegate(double x); caozhy 老大说的太学术化了 这就好象是问“有了汇编语言干嘛还要有basic语言,有了c语言干嘛还要有c#语言”一样喽。站在发展的角度你会发现人需要有变通性的思维,很多时候重要的面对实际而不是死抠一点底层。事件虽然“就是委托”,但是事件在它的领域里要比委托概念更可测试、更标准化、更简单和更有生产率。 委托其实可以看成一种数据类型,不过这个数据类型是你自己定义的,这个数据类型比较特别:它规定了实现它的方法的结构原型,也就是你的事件的类型。因此:可以说事件是一个特殊的委托类型。但是事件:可以订阅多次。多次订阅则会调用相应的处理。(可以看看什么是事件轮循)看代码:using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using System.Drawing;using System.Text;using System.Windows.Forms;namespace WindowsApplication1{ public partial class Form1 : Form { public Form1() { InitializeComponent(); //订阅多次事件 this.Load += new EventHandler(Form1_Load); //加事件:+1 this.Load += new EventHandler(Form1_Load1);//加事件:+1 this.Load += new EventHandler(Form1_Load1);//加事件:+1 //当事件激发时,C#会轮循事件的订阅。也就是说:我们在往Load事件中加处理方法。 //参考类似代码:int n=0;n+=1; //移除事件 this.Load -= new EventHandler(Form1_Load1);//-1,减事件。是不是类似我们的:int n=0;n+=1; } void Form1_Load(object sender, EventArgs e) { MessageBox.Show("Form1_Load"); } void Form1_Load1(object sender, EventArgs e) { MessageBox.Show("Form1_Load1"); } }} 弄了一天的,服了 winform 回车键控制button问题~~~~~~~~~~~~~~~~~~纠结纠结哇 WINFORM中实现GRIDVIEW的嵌套 如何将数据表中的两个字段添加到一个ComboBox控件中 讨论:class和struct得区别 ◆◆◆为什么我播放Flash没有反应 winform中窗体激活时 是哪个属性~ gridview 动态绑定的问题! 希望大家给我帮助!! 如果孟大哥有时间就更好了! 关于水晶报表横向分组的问题!谢谢。 数据库连接 推荐一个 开源下载工具?? vs2010颜色问题
http://www.tracefact.net/CSharp-Programming/Delegates-and-Events-in-CSharp.aspx
public event EventHandler Click
{
add { _click += value; }
remove { _click -= value; }
}这就是说,事件成员本质上是方法。那么,我直接使用公有的委托类型的字段不是更直接么:public EventHandler Click;这么写也是可以的,但是这个代码不能用在接口里,因为接口不允许定义字段。当你想为接口定义事件而不能时,会不会觉得它是个很蹩脚的东西?以上只是从技术角度解释,我更愿意从委托和事件的含义上理解他们的差别。委托是个很技术化的词语,而事件是个更直观的概念。委托是干什么用的,无非是封装个方法而已。如果一个类公开了 Click 委托字段,我会把它理解成“这是点击按钮时会调用的回调方法”,也许还会纠结一下这个字段是不是叫做 ClickCallback 更准确一点,而当它是一个 event 时,它表达的就是“这是点击按钮时引发的事件”,这让我可以更直观的思考,让一堆乱麻似的思维得到一点休息
委托在内部进行调用。
你也可以直接在外部赋值一个函数为委托所使用。但是+=和-=是一种内部通知外部的手段,外部可以再内部发生变化时候进行一定的操作,便捷。。
AA a=new AA();
a+=new handler(test);
void test(object sender,eventargs e)当然+=和-=看起来更具有美感
f积分(f原函数,上限,下限),这里,f原函数就是一个自变量,同时是一个函数。而f积分这个函数就是一个高阶函数。委托的作用就是,代表一种函数类型,我们可以这么定义这个函数:
double f积分(OrgFunctionDelegate func, double low, double high);
delegate double OrgFunctionDelegate(double x);
这个数据类型比较特别:它规定了实现它的方法的结构原型,也就是你的事件的类型。
因此:可以说事件是一个特殊的委托类型。
但是事件:可以订阅多次。多次订阅则会调用相应的处理。(可以看看什么是事件轮循)
看代码:using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;namespace WindowsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent(); //订阅多次事件
this.Load += new EventHandler(Form1_Load); //加事件:+1
this.Load += new EventHandler(Form1_Load1);//加事件:+1
this.Load += new EventHandler(Form1_Load1);//加事件:+1 //当事件激发时,C#会轮循事件的订阅。也就是说:我们在往Load事件中加处理方法。
//参考类似代码:int n=0;n+=1; //移除事件
this.Load -= new EventHandler(Form1_Load1);//-1,减事件。是不是类似我们的:int n=0;n+=1;
} void Form1_Load(object sender, EventArgs e)
{
MessageBox.Show("Form1_Load");
} void Form1_Load1(object sender, EventArgs e)
{
MessageBox.Show("Form1_Load1");
}
}
}