委托和事件
最近看了许多关于委托和事件的介绍和实例,但是对什么时候使用委托,什么时候使用事件,以及当同时可以使用委托或事件时该怎么选择,这些问题还是很迷惑,求解? --------------------编程问答-------------------- 事件只是委托的一个特殊形式.委托能实现的,事件也能实现.委托可以有返回值,事件的委托是不可以有返回值的
我就知道这么多了。 --------------------编程问答-------------------- 谢谢楼上的 有启发 欢迎楼下继续发表高见 --------------------编程问答-------------------- 委托可以理解成为一种特殊的数据类型,本质就是一个“函数变量”,用C系列中的函数指针就很好理解了,
委托定义了一个函数指针,这个函数指针来定一个一个变量的时候,给它赋值的是一堆具有相同签名的函数,可以用一个变量动态调用不同的函数,提供极大的便利,比如把一个函数当作参数传入另一个函数的时候。
事件则是一种操作系统的驱动模式,类似消息驱动,其中使用了委托这种语法形式,具体可以看这篇博文
http://blog.csdn.net/todototry/archive/2010/01/04/5129415.aspx --------------------编程问答-------------------- 正在学习中
路过
帮顶 --------------------编程问答-------------------- C#初学者,学习了 --------------------编程问答-------------------- 嗯 做个记号
对这个也想了解一下 --------------------编程问答-------------------- 委托是实现事件的一种手段。
事件还有其他的实现方法,在.NET基本上都是用委托来实现的。
委托顾名思义就是把本来应该你干的事情交给别人干。 --------------------编程问答--------------------
支持下 --------------------编程问答--------------------
一个函数指针,嘿 --------------------编程问答-------------------- 一般的函数调用是直接jmp(call)到函数地址
用了函数指针,是先取得函数指针包含的值,然后jmp(call)到那个值的地址之中
多了一层的传递,就多了一层的灵活性
而委托是一个类型安全的函数指针实例
--------------------编程问答-------------------- 举个例子
比如你的类里有个int类型的属性NumA
int a;
public int A
{
set{ a = value;}
}
现在我们来做一个捕获这个属性A值改变的事件,事件名称定为NumChanged,下面就可以开始了,很简单
public delegate MyDelegate(object obj,EventArgs e); //定义委托
public event MyDelegate NumChanged; //定义事件
private void OnNumChange() //事件监听
{
if(NumChanged != null)
{
NumChanged(obj,e);
}
}
最后,我们把事件监听放在属性赋值语句的后面
public int A
{
set{
a = value;
OnNumChange(); //这样就完成了一个NumChanged,因为是在赋值后触发的这个事件,所以我们用过去式命名
}
}
最后再说一遍,这个事件的作用就是在属性A改变后,做某些处理 --------------------编程问答-------------------- 突然瞟到楼主的结贴率,汗了一下 --------------------编程问答-------------------- 谢谢咯 --------------------编程问答--------------------
委托好像可以理解为 一组函数 的集合 调用的时候依据参数的不同而选择不同的函数
我们老师将的时候我是这么理解的 --------------------编程问答-------------------- windows编程,在窗体UI层使用匿名委派,能够更好的实现代码的封装。
委派就是可以让你把方法当做方法的参数进行使用
.net封装了大部分事件
很少要自己去写事件 --------------------编程问答-------------------- 学习了... --------------------编程问答--------------------
应该倒过来说,事件可以实现的,委托也可以实现。不是说扩展的东西就一定更复杂,事件就是让委托更傻瓜化。
不过事件被编译器包装得更加专一,更简单直观。编译器限制了事件只能写成及其固定的写法。
而委托则用法很灵活,似乎也显得复杂一点。 --------------------编程问答-------------------- 学习下,我感觉委托就是一种自定义类型,和特定类型函数对应 --------------------编程问答-------------------- 顺便强调一下,一旦你声明你自己的委托或者事件,其实都是自己定义了一个类型。之后当你使用委托或者事件声明变量,你就在面向委托/事件对象编程。委托(以及事件)实际上是面向对象的。
我们在谈论面向对象时往往混淆对象类和对象实例,事件/委托也有这种倾向,我们经常混淆委托类和委托对象、事件类和事件对象,都简称为委托或者事件。如果我遇到可以谨慎地区分事件类和事件对象、委托类和委托对象的人,我会相信他真的理解了事件或者委托,再也不用类比为c指针才能理解了。
--------------------编程问答--------------------
这恐怕是完全误会了编译器了,这个误会会产生很多似是而非的结论。
Action d;
d=abc;
.....
d();
.....
}
private void abc()
{
....
}
以上代码中,并不是给d赋值以函数abc,编译器实际编译出来的代码仍然是类似这样的形式:
[code=C#]Action d;
d=new Action(abc);
即,委托对象d(或者说成“变量d所引用的委托对象”才更准确一些)被用一个Action类型的对象实例赋值,而这个对象使用指向函数abc的指针(这个时候才用到指针概念)来实例化。
因此,委托在及其复杂的结构中使用到了一个或者无数个函数指针,委托仍然是面向对象的,它自己并不就是一个函数指针。 --------------------编程问答-------------------- 关于对象类和对象实例的区别,我拿 11 楼的代码做个例子:
public delegate MyDelegate(object obj,EventArgs e); //定义委托
public event MyDelegate NumChanged; //定义事件
这里,MyDelegate 其实是一个class,而NumChanged则只是一个引用 MyDelegate 类型的对象的变量。 --------------------编程问答--------------------
我也瞟到了 所以我一直keep Silence --------------------编程问答-------------------- .net 中的事件类eventhandler和eventhandler<...>其实都是Delegate(子类),它们被广泛用于各种事件对象的(的变量引用的)声明中。
事件其实很简单,因为它毕竟是被编译器刻意简化了的代理。我还是举一个代理的例子,一个用于求阶乘的代理对象可以这样定义:
Func<int, int> factorial = null;
factorial = n =>
{
if (n == 0)
return 1;
else
return n * factorial(n - 1);
};
而求出9的阶乘就可以这样:
int result=factorial(9);
这里,计算阶乘的方法被一个变量factorial传递着。在获取result值之前,获取有人修改了factorial变量所引用的对象,用另外一个Delegate来代替了上面定义的Delegate。 --------------------编程问答-------------------- 难得看到sp1234讲这么基础的内容。 --------------------编程问答--------------------
因为Delegate很好玩也很强大。我上一次讨论这个阶乘Delegate,就是因为用来说明函数编程语言也没有什么新鲜的、c#早就有那种能力。 --------------------编程问答-------------------- 事件的作用,主要是我们用于对设计进行“依赖倒置”,以便缩小问题的范围,尽早让架构运行起来而不是纠缠于旁支。完成依赖倒置基本上就可以说明事件通知机制的全部功能。
而Delegate更显得“原型”一些,功能也更丰富一些。 --------------------编程问答-------------------- 以后期待sp1234多讲这些语言基础深层性的内容。
感谢。 --------------------编程问答-------------------- 哎,叹一声,叹不尽我心中苦楚 --------------------编程问答-------------------- sp1234说得太抽象了。
城府不深根本看不透。 --------------------编程问答-------------------- 委托是学习事件操作的基础 --------------------编程问答-------------------- 委托,就是一个声明一个小工作流程。 --------------------编程问答-------------------- 谢谢各位的指点
我想知道 大家在什么情况下会用到委托和事件 或者说 在用之前的思路是什么 --------------------编程问答-------------------- 事件是一种驱动模型
委托是事件实现时候用到的一种技术 --------------------编程问答-------------------- 这种问题真的是只有真正的高手才能彻底讲明白。。。
对于菜鸟来说,喜欢简单的例子和通俗的语句。。。
http://www.cnblogs.com/jimmyzhang/archive/2007/09/23/903360.html
看看上面这篇文章吧!!!相信你一定受益匪浅!!! --------------------编程问答-------------------- 受教了…… --------------------编程问答--------------------
UP --------------------编程问答--------------------
using System;--------------------编程问答-------------------- --------------------编程问答-------------------- --------------------编程问答--------------------
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
#region "变量定义"
IList<Person> p = new List<Person>()
{
new Person { Name = "lizeren", Address = "wenzhou", Remarks = "ailili", Sex=SexType.男 } ,
new Person {Name="wanglili",Address="jilin",Remarks="aizeren",Sex=SexType.女 },
new Person {Name="xuhongfei",Address="wenzhou",Remarks="py",Sex=SexType.女 },
new Person("lizeren","wenzhou","ailili","男")
};
BindingSource bds = null;
#endregion
private void Form1_Load(object sender, EventArgs e)
{
bds = new BindingSource();
bds.DataSourceChanged += new EventHandler((o, ex) =>
{
this.dataGridView1.DataSource = bds;
});
bds.DataSource = p;
//this.dataGridView1.DataSource = bds;
}
Form2 Frm = null;
//添加数据
private void toolStripLabel1_Click(object sender, EventArgs e)
{
if (Frm == null)
{
Frm = new Form2();
Frm.Text = "添加数据";
#region "事件"
//添加数据行
Frm.button1.Click += new EventHandler((sen, eb) =>
{
if (Frm.PersonValue != null)
{
bds.Add(Frm.PersonValue);
Frm.Close();
}
else
{
MessageBox.Show(this, "格式不正确");
}//if
});
//
//关闭按钮
//
Frm.button2.Click += new EventHandler((se, eb) =>
{
Frm.Close();
});
Frm.FormClosed += new FormClosedEventHandler((send, ec) =>
{
Frm = null;
});
#endregion
Frm.Show(this);
}
else
{
Frm.Activate();
}//if
}
//修改数据
private void toolStripLabel2_Click(object sender, EventArgs e)
{
if (Frm == null)
{
Frm = new Form2();
Frm.Text = "修改数据";
if (bds.Current != null)
{
Frm.PersonValue = (Person)bds.Current;
}
#region "事件"
//
//修改数据
//
Frm.button1.Click += new EventHandler((sen, ex) =>
{
Person CurPer = (Person)bds.Current;
Person gp = Frm.PersonValue;
if (gp != null)
{
CurPer.Name = gp.Name;
CurPer.Address = gp.Address;
CurPer.Remarks = gp.Remarks;
CurPer.Sex = gp.Sex;
bds.CurrencyManager.Refresh();
Frm.Close();
}
else
{
MessageBox.Show(this, "格式不正确");
}
});//event
//
//关闭Form2
//
Frm.button2.Click += new EventHandler((se, eb) =>
{
Frm.Close();
});
Frm.FormClosed += new FormClosedEventHandler((send, ec) =>
{
Frm = null;
});
#endregion
Frm.Show(this);
}
else
{
Frm.Activate();
}
}
private void toolStripButton1_Click(object sender, EventArgs e)
{
IList<Person> pl = (IList<Person>)bds.List;
}
private void toolStripButton2_Click(object sender, EventArgs e)
{
bds.DataSource = new List<Person>();
}
private void toolStripButton3_Click(object sender, EventArgs e)
{
bds.DataSource = p;
}
}
}
基本上南辕北辙,其实事件和委托之间本可以没有任何关系的,事件是一种消息处理机制,有发布者和订阅者,使用事件处理时这种订阅机制正适合委托来实现,所以他们就有了关系。 --------------------编程问答-------------------- --------------------编程问答-------------------- 对C#的事件和委托我一直十分迷茫,没有VB来的简单
补充:.NET技术 , C#