当前位置:编程学习 > C#/ASP.NET >>

委托和事件

最近看了许多关于委托和事件的介绍和实例,但是对什么时候使用委托,什么时候使用事件,以及当同时可以使用委托或事件时该怎么选择,这些问题还是很迷惑,求解? --------------------编程问答-------------------- 事件只是委托的一个特殊形式.委托能实现的,事件也能实现.
委托可以有返回值,事件的委托是不可以有返回值的 
我就知道这么多了。 --------------------编程问答-------------------- 谢谢楼上的 有启发 欢迎楼下继续发表高见 --------------------编程问答-------------------- 委托可以理解成为一种特殊的数据类型,本质就是一个“函数变量”,用C系列中的函数指针就很好理解了,
委托定义了一个函数指针,这个函数指针来定一个一个变量的时候,给它赋值的是一堆具有相同签名的函数,可以用一个变量动态调用不同的函数,提供极大的便利,比如把一个函数当作参数传入另一个函数的时候。

事件则是一种操作系统的驱动模式,类似消息驱动,其中使用了委托这种语法形式,具体可以看这篇博文
http://blog.csdn.net/todototry/archive/2010/01/04/5129415.aspx --------------------编程问答-------------------- 正在学习中
路过
帮顶 --------------------编程问答-------------------- C#初学者,学习了 --------------------编程问答-------------------- 嗯 做个记号 
对这个也想了解一下 --------------------编程问答-------------------- 委托是实现事件的一种手段。

事件还有其他的实现方法,在.NET基本上都是用委托来实现的。

委托顾名思义就是把本来应该你干的事情交给别人干。 --------------------编程问答--------------------
引用 7 楼 cuike519 的回复:
委托是实现事件的一种手段。

事件还有其他的实现方法,在.NET基本上都是用委托来实现的。

委托顾名思义就是把本来应该你干的事情交给别人干。


支持下 --------------------编程问答--------------------
引用 7 楼 cuike519 的回复:
委托是实现事件的一种手段。

 事件还有其他的实现方法,在.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封装了大部分事件
很少要自己去写事件 --------------------编程问答-------------------- 学习了... --------------------编程问答--------------------
引用 1 楼 wangyue4 的回复:
委托能实现的,事件也能实现.


应该倒过来说,事件可以实现的,委托也可以实现。不是说扩展的东西就一定更复杂,事件就是让委托更傻瓜化。

不过事件被编译器包装得更加专一,更简单直观。编译器限制了事件只能写成及其固定的写法。

而委托则用法很灵活,似乎也显得复杂一点。 --------------------编程问答-------------------- 学习下,我感觉委托就是一种自定义类型,和特定类型函数对应 --------------------编程问答-------------------- 顺便强调一下,一旦你声明你自己的委托或者事件,其实都是自己定义了一个类型。之后当你使用委托或者事件声明变量,你就在面向委托/事件对象编程。委托(以及事件)实际上是面向对象的。

我们在谈论面向对象时往往混淆对象类和对象实例,事件/委托也有这种倾向,我们经常混淆委托类和委托对象、事件类和事件对象,都简称为委托或者事件。如果我遇到可以谨慎地区分事件类和事件对象、委托类和委托对象的人,我会相信他真的理解了事件或者委托,再也不用类比为c指针才能理解了。

--------------------编程问答--------------------
引用 3 楼 todototry 的回复:
给它赋值的是一堆具有相同签名的函数,


这恐怕是完全误会了编译器了,这个误会会产生很多似是而非的结论。

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 类型的对象的变量。 --------------------编程问答--------------------
引用 12 楼 lovelan1748 的回复:
突然瞟到楼主的结贴率,汗了一下

我也瞟到了 所以我一直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讲这么基础的内容。 --------------------编程问答--------------------
引用 24 楼 xupeihuagudulei 的回复:
难得看到sp1234讲这么基础的内容。


因为Delegate很好玩也很强大。我上一次讨论这个阶乘Delegate,就是因为用来说明函数编程语言也没有什么新鲜的、c#早就有那种能力。 --------------------编程问答-------------------- 事件的作用,主要是我们用于对设计进行“依赖倒置”,以便缩小问题的范围,尽早让架构运行起来而不是纠缠于旁支。完成依赖倒置基本上就可以说明事件通知机制的全部功能。

而Delegate更显得“原型”一些,功能也更丰富一些。 --------------------编程问答-------------------- 以后期待sp1234多讲这些语言基础深层性的内容。
感谢。 --------------------编程问答-------------------- 哎,叹一声,叹不尽我心中苦楚 --------------------编程问答--------------------
引用 19 楼 sp1234 的回复:
顺便强调一下,一旦你声明你自己的委托或者事件,其实都是自己定义了一个类型。之后当你使用委托或者事件声明变量,你就在面向委托/事件对象编程。委托(以及事件)实际上是面向对象的。

 我们在谈论面向对象时往往混淆对象类和对象实例,事件/委托也有这种倾向,我们经常混淆委托类和委托对象、事件类和事件对象,都简称为委托或者事件。如果我遇到可以谨慎地区分事件类和事件对象、委托类和委托对象的人,我会相信他真的理解了事件或者委托,再也不用类比为c指针才能理解了。
sp1234说得太抽象了。
城府不深根本看不透。 --------------------编程问答-------------------- 委托是学习事件操作的基础 --------------------编程问答-------------------- 委托,就是一个声明一个小工作流程。 --------------------编程问答-------------------- 谢谢各位的指点 
我想知道  大家在什么情况下会用到委托和事件 或者说 在用之前的思路是什么 --------------------编程问答-------------------- 事件是一种驱动模型
委托是事件实现时候用到的一种技术 --------------------编程问答-------------------- 这种问题真的是只有真正的高手才能彻底讲明白。。。
对于菜鸟来说,喜欢简单的例子和通俗的语句。。。
http://www.cnblogs.com/jimmyzhang/archive/2007/09/23/903360.html
看看上面这篇文章吧!!!相信你一定受益匪浅!!! --------------------编程问答-------------------- 受教了…… --------------------编程问答--------------------
引用 33 楼 todototry 的回复:
事件是一种驱动模型
委托是事件实现时候用到的一种技术


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;            
        }
    }
}
--------------------编程问答-------------------- --------------------编程问答-------------------- --------------------编程问答--------------------
引用 1 楼  的回复:
事件只是委托的一个特殊形式.委托能实现的,事件也能实现.
委托可以有返回值,事件的委托是不可以有返回值的 
我就知道这么多了。

基本上南辕北辙,其实事件和委托之间本可以没有任何关系的,事件是一种消息处理机制,有发布者和订阅者,使用事件处理时这种订阅机制正适合委托来实现,所以他们就有了关系。 --------------------编程问答-------------------- --------------------编程问答-------------------- 对C#的事件和委托我一直十分迷茫,没有VB来的简单
补充:.NET技术 ,  C#
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,