委托和事件的直接理解

委托和事件的直接理解
委托和事件的直接理解

初学者在理解委托和事件时常常被msdn搞糊涂,为了让初学.net的人快速应用.net的委托和事件模型编程,我在这里主要是提出理解的关键,以下代码都可直接运行,先看下面的代码。

using System;

namespace delegeteTest

{

class delegeteClass

{

public delegate void fHandler(int a); //关键-此行可以看成类的声明

public fHandler f0;

public void d(int a,int b )

{

int c=a+b;

f0(c);

}

}

class test

{

public void output(int mun)

{

System.Console .WriteLine ("{0}",mun);

}

[STAThread]

static void Main(string[] args)

{

test t=new test ();

delegeteClass dc=new delegeteClass ();

dc.f0 =new delegeteTest.delegeteClass.fHandler (t.output);//实例的初始化 dc.d(2,3);

}

}

}

解释一下"关键": 实际上 public delegate void fHandler(int a);可以看成如下:

class fHandler

{.....}

类内部由编译器自动完成,是一个sealed类通过反汇编可以看到,是一个类的声明,它检查加入自己的函数的信息,如,返回值和参数类型

现在熟悉vc++的人可能感觉到public delegate void fHandler(int a);这句就象一个宏

现在好了既然是个类的定义,那么也可以直接拿到命名空间下了

using System;

namespace delegeteTest

{

public delegate void fHandler(int a);//fHandler现在上升到了类的层次

class delegeteClass

{

public fHandler f0;//声明了委托fHandler的实例f0;

public fHandler f1;//也可以再声明一个fHandler类的实例f1;

public void d(int a,int b )

{

int c=a+b;

f0(c);

}

}

class test

{

public void output(int mun)

{

System.Console .WriteLine ("{0}",mun);

}

[STAThread]

static void Main(string[] args)

{

test t=new test ();

delegeteClass dc=new delegeteClass ();

dc.f0 =new delegeteTest.fHandler (t.output);//此行做相应的修改

dc.d(2,3);

}

}

}

有以上可知public delegate void fHandler(int a)这行代码只能放在能够声明类的地方,自然fH andler.后面的函数都是静态方法了,如fHandler.Equals (...);

那么fHandler到底声明了什么? 实际上是声明了函数的类型,既函数的有关信息(如返回值,参数类型)。说到委托还是要说一下委托类型的实例。在msdn中的很多地方,(委托)这个词指的是委托类型的实例,它拥有了一个列表,列表的每一项包含了函数信息和函数所在的对象的引用。

在声明fHandler类的实例f0的时候,f0还不能用,是空的,所以f0需要初始化 dc.f0 =new dele geteTest.fHandler (t.output); 初始化的参数包含了两个信息 t--对象的引用,output--函数信息,如果把初始化的这句注释掉,你运行一下看有什么信息----“未将对象引用设置到对象的实例”。另外outp ut函数的参数和返回值需要和fHandler的类声明一致,这是由编译器在编译时检查的。

经过初始化之后现在实例中有了一项数据(实际上大多数只有一项,这样效率比较高,也就是s ingle cast的,此时实例是Delegate类型的(注意是大写的D))。

现在说一下委托的多播(multi cast),实际上委托的多播就是把列表里的每一项函数调用一次),但是多播的效率不是很高的所以委托的大部分实例都是单播(single cast),另外可能委托的实例会根据列表内函数的个数来运行不同的机制(这里我们就没必要研究它了)。看下面的代码:

namespace delegeteTest

{

public delegate void fHandler(int a);

class delegeteClass

{

public fHandler f0;

public fHandler f1;

public void d(int a,int b )

{

int c=a+b;

f1(c); //合并指针列表的多播委托

}

}

class test

{

public void output(int mun)

{

System.Console .WriteLine (" 函数1显示{0}",mun);

}

public void output1(int mun)

{

System.Console .WriteLine (" 函数2显示{0}",mun);

}

[STAThread]

static void Main(string[] args)

{

test t=new test ();

delegeteClass dc=new delegeteClass ();

dc.f0 =new delegeteTest.fHandler (t.output);

dc.f1 =new fHandler (t.output1 );

System.Console .WriteLine ("第一次触发");

dc.d (2,3);//第一次触发

dc.f1 =(fHandler)https://www.360docs.net/doc/937813937.html,bine (dc.f0 ,dc.f1 );//合并生成新的]函数列表 dc.f1 =(fHandler)https://www.360docs.net/doc/937813937.html,bine (dc.f1 ,dc.f0 );//同上

System.Console .WriteLine ("第二次触发");

dc.d(2,3);//第二次触发

}

}

}

实际上dc.f1 =(fHandler)https://www.360docs.net/doc/937813937.html,bine (dc.f1 ,dc.f0 );和dc.f1 =(fHandler)Delegat https://www.360docs.net/doc/937813937.html,bine (dc.f1 ,dc.f0 );效果是一样的;由上面的例子可知我们完全可以由delegate 来构造我们自己的事件。微软为了方便大家进行编程,为我们提供了event。

using System;

namespace delegeteTest

{

public delegate void fHandler(int a);

class delegeteClass

{

public fHandler f0;

public fHandler f1;

public event fHandler f3; //关键--实际上此行也可以看成一个宏

public void d(int a,int b )

{

int c=a+b;

f3(c); // 改由event进行

}

}

class test

{

public void output(int mun)

{

System.Console .WriteLine (" 第1显示{0}",mun);

}

public void output1(int mun)

{

System.Console .WriteLine (" 第2显示{0}",mun);

}

[STAThread]

static void Main(string[] args)

{

test t=new test ();

delegeteClass dc=new delegeteClass ();

dc.f0 =new delegeteTest.fHandler (t.output);

dc.f1 =new fHandler (t.output1 );

dc.f3 +=new fHandler(t.output); //f3是event

System.Console .WriteLine ("第一次触发");

dc.d (2,3);//第一次触发

System.Console .WriteLine ("第二次触发");

dc.f3 +=(fHandler)https://www.360docs.net/doc/937813937.html,bine (dc.f0 ,dc.f1 );//添加列表到f3

dc.d(2,3);//第二次触发

}

}

}

通过ildasm反汇编可以看到public event fHandler f3宏声明了两个成员

.field private class delegeteTest.fHandler f3和对f3的一个包装:

.event delegeteTest.fHandler f3

{

.addon instance void delegeteTest.delegeteClass::add_f3(class delegeteTest.fHandler)

.removeon instance void delegeteTest.delegeteClass::remove_f3(class delegeteTest.fHandler) },

所以上面红色的代码可以替换成如下:

private fHandler _f3;//由于不能与属性名相同,所以用_f3,是私有

public event fHandler f3

{

add

{

this._f3 += value;

}

remove

{

this._f3 -= value;

}

}

event 关键字方便了大家的习惯,同时它(由event定义的事件)在类的外部使用时隐藏了它的成员函数(这一点非常重要,几乎就是使用event关键字的原因),并且只能用“+=”和“-=”来操作,除此之外和直接声明public fHandler f3没有区别。它可以和上面的f0,f1一样允许有各种参数和返回值(Event Handler是一个特定的委托,没有返回值,参数是object和EventArgs类(或继承)的)。是在委托基础

上的。实际上我们都能用delegate 来构造我们想要的事件,这就是delegate 在.net里的地位很高的原因。

下面我就说说一般控件的事件模型

我先谈一下控件里的"On事件名"这个函数如:OnTextChange(EventArgs e),类似的有很多,实际上这是一种编程方面的习惯,他代表的是引发这个TextChanged事件(当然和上面一样,包含一个委托onTex tChanged和一个event包装),具体的说就是在Text变量已经被赋值后执行的一个函数OnTextChanged(),OnTextChanged()里面包含了类似onTextChanged(e)这样的引发事件的代码。如果你重写了OnTextChange d(),而没有在(重写的函数)里添加base.OnTextChanged(e);那么你在外部添加的TextChanged事件的处理程序,永远也不会触发到,也就是TextChanged事件失效了。

C#里的委托和事件实现Observer

C#里的委托和事件实现Observer 一、委托的简介 1、委托的声明: delegate HandlerName ([parameters]) 例如: public delegate void PrintHandler(string str); 委托声明定义了一种类型,它用一组特定的参数以及返回类型来封装方法。对于静态方法,委托对象封装要调用的方法。对于实例方法,委托对象同时封装一个实例和该实例上的一个方法。如果您有一个委托对象和一组适当的参数,则可以用这些参数调用该委托。 2、委托的使用: using System; public class MyClass { public static void Main() { PrintStr myPrinter = new PrintStr(); PrintHandler myHandler = null; myHandler += new PrintHandler(myPrinter.CallPrint); // 将委托链接到方法,来实例化委托 if(myHandler!=null) myHandler("Hello

World!"); // 调用委托,相当于匿名调用委托所链接的方法 Console.Read(); } } public delegate void PrintHandler(string str); // 声明委托类型 public class PrintStr { public void CallPrint(string input) { Console.WriteLine(input); } } 在C#中使用委托方法: ·创建委托所使用的方法必须和委托声明相一致(参数列表、返回值都一致) ·利用 +=、-=来进行委托的链接、取消链接或直接使用https://www.360docs.net/doc/937813937.html,bine和Delegate.Remove方法来实现 ·可以使用MulticastDelegate的实例方法GetInvocationList()来获取委托链中所有的委托

C#委托及事件

C#委托及事件 在C#中,委托(delegate)是一种引用类型,在其他语言中,与委托最接近的是函数指针,但委托不仅存储对方法入口点的引用,还存储对用于调用方法的对象实例的引用。 简单的讲委托(delegate)是一种类型安全的函数指针,首先,看下面的示例程序,在C++中使用函数指针。 首先,存在两个方法:分别用于求两个数的最大值和最小值。 int Max(int x,int y) { return x>yx:y; } int Min(int x,int y) { return x } 上面两个函数的特点是:函数的返回值类型及参数列表都一样。那么,我们可以使用函数指针来指代这两个函数,并且可以将具体的指代过程交给用户,这样,可以减少用户判断的次数。 下面我们可以建立一个函数指针,将指向任意一个方法,代码如下所示: 建立一个委托类型,并声明该委托可以指向的方法的签名(函数原型)delegate void MyDelegate(int a,int b); 2.建立一个委托类的实例,并指向要调用的方法 用委托类实例调用所指向的方法 int c=md(4,5); 下面通过实例来演示C#中委托的使用。

案例操作020601:利用委托实现方法的 动态调用 首先,添加如下控件: 两个RadioButton,分别用来让用户选 择求最大值以及求最小值 二个TextBox,用来输入两个操作数 一个TextBox,用来显示运算结果 一个Button,用来执行运算 界面如下图所示: 下一步,在窗口中添加两个方法:Max,Min,这两方法的代码如下: int Max(int x,int y) { return x>yx:y; } int Min(int x,int y) { return x } 窗口中的代码,如下图所示:

C#委托事件详解

C# 中的委托和事件 引言 委托和事件在 .Net Framework中的应用非常广泛,然而,较好地理解委托和事件对很多接触C#时间不长的人来说并不容易。它们就像是一道槛儿,过了这个槛的人,觉得真是太容易了,而没有过去的人每次见到委托和事件就觉得心里别(biè)得慌,混身不自在。本文中,我将通过两个范例由浅入深地讲述什么是委托、为什么要使用委托、事件的由来、.Net Framework中的委托和事件、委托和事件对Observer设计模式的意义,对它们的中间代码也做了讨论。 将方法作为方法的参数 我们先不管这个标题如何的绕口,也不管委托究竟是个什么东西,来看下面这两个最简单的方法,它们不过是在屏幕上输出一句问候的话语: public void GreetPeople(string name) { // 做某些额外的事情,比如初始化之类,此处略 EnglishGreeting(name); } public void EnglishGreeting(string name) { Console.WriteLine("Morning, " + name); } 暂且不管这两个方法有没有什么实际意义。GreetPeople用于向某人问好,当我们传递代表某人姓名的name参数,比如说“Jimmy”,进去的时候,在这个方法中,将调用EnglishGreeting方法,再次传递name参数,EnglishGreeting则用于向屏幕输出“Morning, Jimmy”。

现在假设这个程序需要进行全球化,哎呀,不好了,我是中国人,我不明白“Morning”是什么意思,怎么办呢?好吧,我们再加个中文版的问候方法: public void ChineseGreeting(string name){ Console.WriteLine("早上好, " + name); } 这时候,GreetPeople也需要改一改了,不然如何判断到底用哪个版本的Greeting问候方法合适呢?在进行这个之前,我们最好再定义一个枚举作为判断的依据: public enum Language{ English, Chinese } public void GreetPeople(string name, Language lang){ //做某些额外的事情,比如初始化之类,此处略 swith(lang){ case Language.English: EnglishGreeting(name); break; case Language.Chinese: ChineseGreeting(name); break; } } OK,尽管这样解决了问题,但我不说大家也很容易想到,这个解决方案的可扩展性很差,如果日后我们需要再添加韩文版、日文版,就不得不反复修改枚举和GreetPeople()方法,以适应新的需求。 在考虑新的解决方案之前,我们先看看 GreetPeople的方法签名:

唯一看明白额委托与事件讲解

一、在控制台下使用委托和事件 我们都知道,C#中有“接口”这个概念,所谓的“接口”就是定义一套标准,然后由实现类来具体实现其中的方法,所以说“接口,是一组类的抽象”。同样道理,我们可以将“委托”理解为“方法的抽象”,也就是说定义一个方法的模板,至于这个方法具体是怎么样的,就由方法自己去实现。 我们知道接口的最大好处就是可以实现多态,同理,“委托”是可以实现方法的多态,当我们想调用某个具体方法的时候,我们不直接调用这个方法,而是去调用这个委托。当然,我们必须在具体方法和委托之间建立某种关联。 下面我们来看例子。 首先,我们定义一个委托: public delegate void SaySomething(string name); 这跟抽象方法的语法格式很相似,只是多了一个关键字delegate。既然是对方法的一种抽象,那么我们最关注的当然就是方法的返回值以及方法的参数了。所以上面红色的部分就是我们定义出来的一个规矩,如果某个方法想委托我去做事,那么请你遵循我的规矩,就是返回值为void,参数为一个字符串。我们这个委托的含义是,当某个人来了,就向他说点东西。 好,既然我们已经定义了这个规矩,下面我们就定义具体的方法了。 public void SayHello(string name) { Console.WriteLine("Hello," + name + "!"); } public void SayNiceToMeetYou(string name) { Console.WriteLine("Nice to meet you," + name + "!"); } 我们这里一共定义了两个方法,一个是向某人说Hello,另一个是向某人说Nice to meet you。我们看到,这里定义的两个方法的返回值和参数跟我们前面定义的“委托”是一致的。 接下来,我们来看事件。 public event SaySomething come;

委托事件1

委托 定义委托的语法和定义方法比较相似,只是比方法多了一个关键字delegate,我们都知道方法就是将类型参数化,所谓的类型参数化就是说该方法接受一个参数,而该参数是某种类型的参数,比如int、string等等;而委托是将方法参数化,说了上面的那个类型参数化之后,相信你也能猜到方法参数化的意思了,对,就是将方法作为一个参数传到一个委托中。 首先来看看声明委托的语句: public deletate void MyDelegate(); public:访问修饰符delegate:关键字void:返回类型MyDelegate:委托名称( ):参数列表 看到声明大家会想了,为什么该委托的返回值,参数列表要这样的,我不能返回一个string,一个int么?我不能给委托加几个参数么?答案是:当然可以,但委托的定义是相对于方法来说的,因为得你的委托最终是要来注册方法的,而你的方法是具有某种签名的,所以你要给怎样签名的方法来声明一个委托,该委托就要和该方法具有同等的签名,就类似于你用一个int 类型的变量去接受一个string类型的值,显然是不行的(个人理解).... * 委托只要定义就可以了,我们并不需要关心他的实现 委托的使用 注册委托有两种方法: 第一种:直接将方法赋值[=]或者用“+=”给一个委托==>委托名=[+=] 方法名 第二种:委托本质也是一个类,只是一个特殊的类,所以我们也可以实例化一个委托对象通过委托构造函数来注册委托==》委托名对象名= new 委托名(方法名)

了解了委托的声明和使用,我们就可以来看小例子来加深理解了 首先看看界面: 界面上就是简单的四个按钮两个属于委托,两个属于事件,都是一个用来执行,一个用来干扰,以便于来理解委托事件 然后看后台代码,首先我定义了一个Test类,声明委托,实例了委托,还声明了事件,写了个方法用来触发事件,代码如下: 1public class Test 2 { 3//声明一个委托 4public delegate void MyDelegate(); 5 6//创建一个委托实例 7public MyDelegate myDel; 8//声明一个事件 9public event MyDelegate EventMyDel; 10 11//事件触发机制(必须和事件在同一个类中) 外界无法直接用EventMyDel()来触发事件 12public void DoEventMyDel() 13 { 14 EventMyDel(); 15 } 16 }

委托与事件 机制

Button1.Click+=new EventHandler(Button1_Click);-----------------@1 大家都熟悉的一段代码,Button1.Click是事件(也可以说是一条委托链),EventHandler 是委托,Button1_Click是订阅事件的人,也可以说是委托的人。 通过这样的机制,一个事件可以有多个订阅者,从而可以实现点击button可以响应多个方法。委托,顾名思义,委托给别人。 事件,“发布者/订阅者” 模式,发布者发布一个事件,订阅者订阅这个事件,当事件触发时,就会通知订阅者。通知这个过程是通过委托来实现的。 大家想象一下这个情景,经理有一个项目,计划A君负责美工方面,B君负责程序方面,将项目一分为二;于是一天,在用餐的时候告诉他们这个计划。 发布者:经理---------@2 订阅者订阅这个事件原因:A,B君是经理的部下 -------------@3 事件:经理分配了A,B一个项目-------------@4 触发事件的原因:经理有个计划----------------@5 通知方式(委托):”在用餐的时候告诉“方式----------------@6 public delegate void OneThing(object sender, CustomEventArgs e);定义一个委托,返回值为空,委托名OneThing,相当于@1中的EventHandler,有两个参数分别为触发事件的对象和事件信息。 Custom EventArgs必须继承于EventArgs public class CustomEventArgs : EventArgs

论C#中的委托与事件

论C#中的委托与事件 在C#里,委托与事件类是两个不易理解的概念。主要阐述对委托与事件的理解,同时结合Observer设计模式与.NET Framework规范,针对生活中的案例来辨析委托与事件的应用。 标签:委托;事件Observer设计模式;.NET Framework C#中的委托类似于C++中的函数指针,功能却更多。事件是在委托的基础上的一种结构,类似于委托的变量,在界面的控件中处处都有应用。 1 什么是委托 委托的申明格式:修饰符delegate 返回值数据类型委托名(形参列表)。 例如:Delegate int AbcDel(string s, bool b);是一个委托申明,每一个委托都有自己的签名,就是说AbcDel这个委托有string 和bool类型的形参,返回一个int类型数据,即具有这样的函数签名。委托类似于函数指针,它能够引用函数,通过传递地址的机制完成。委托是一个类,当对它实例化时,要提供一个引用函数,将其作为它构造函数的参数。例如:private int AbcFun (string str, bool bln){},则可以把这个函数传给AbcDel的构造函数,因为它们签名一致。AbcDel sd = new SomeDelegate(AbcFun),sd 引用了AbcFun,也就是说,AbcFun已被sd所登记注册,如果你调用sd,AbcFun这个函数即会被调用。 2 事件的理解 事件的申明格式:修饰符event 委托名事件名; 例如:public event AbcDel Boil;//AbcDel为委托名 Boil事件的声明与之前委托变量sd的声明唯一的区别是多了event关键字。声明事件类似于声明一个委托类型的变量。 3 Observer设计模式 假设热水器系统由两部分组成:热水器、警报器,由不同厂商进行了组装。热水器仅负责烧水;警报器在水烧开时发出警报,当水温超过95度,就发出警报。我们需要应用委托与事件来模拟此过程。 Observer设计模式是为了定义对象间的一种一对多的依赖关系,以便于当一个对象的状态改变时,其他依赖于它的对象会被自动告知并更新。Observer模式是一种松耦合的设计模式。它包括两类对象:

C#委托与事件以及应用

这些很重要在MVC EF4.1 里都会有很多拉姆达表达式的影子在做组件开发用户控件开发事件的运用一定也是少不了的稍微深入点儿的说用于两个对象之间的通讯用来解耦用委托事件是很不错的选择而设计模式里的观察者模式也是基于委托事件的应用还有做winform 开发的里的线程WPF SL 的异步调用等都是有这委托的影子的所以这个还是很重要的。也是一定要掌握的~ 希望通过这篇文章能让大家更加了解委托以及如何运用~ 一.委托以及延伸 先看下MSDN 的介绍吧~------ delegate 通俗的说委托就是可以实现把方法做为变量来传递 1.先写个最简单的委托的用法 静态的和非静态方法的 结果会输出 您好wlf

Hello wlf 这是最原始的委托 2. 进化为匿名方法 声明完委托后还要声明方法是不是很麻烦如果不声明方法用匿名方法可以帮我们看 代码减少了很多吧~ 3.再进化为拉姆达表达式 上面的虽然简单了不少但是还能更简单的用拉姆达表达式~ 看这就是拉姆达表达式的演变一定要会这个~ 因为在EF LINQ 等有很多用拉姆达表达式的~ 4.用Action 和Func继续简化 上面的代码以及很简单了但是还有个很不爽的一点~ 要声明委托!可以不声明么?当然可以~ 先看MSDN介绍Action和Func 通俗的讲这两个都是用来帮你声明委托 Action 用于帮你声明没用返回值的委托Func则是有返回值的最后一个参数为返回值

看~ 以前的版本总是要声明一个HelloWorld 的委托现在只有两行代码就可以了下面顺便掩饰了有返回值的func 的例子。第一个参数是传递 参数的类型第二个是返回值的类型~ 这里说下这俩函数都有16个重载~ 所以多个参数是没问题的~ 5.说说委托的好处 委托的好处应用文章开始已经说了很多了这里就拿文章开头的例子体会下委托的好处 当我们再多一种语言来问好时只需增加一种Action 即可而不需要改动sayHello 方法否则这里将充满了if else 的判断 6.工作里的应用 再LINQ 或EF 里都有个很重要的数据刷选的功能WHERE 它的参数就是Func 直接上代码自己看注释~

unity3D学习之委托、事件全解析(二)

废话就不多说了,直接进入今天的主题-事件在我们所接触到的事件一般分两种:一种是自定义的,自定义的事件需要自己对其进行赋值。 一种是控件提供方定义的,如:ngui,控件事件只需要查找控件定义的事件列表,选择所需要的进行操作即可。 当然,我们的话题是上面第一种啦。 实例模拟场景为:文章来自【狗刨学习网】 游戏战斗中,猪脚在指定的一片区域中,存在4只怪物,他的目的就是一只一只找到并消灭该区域的怪物。 简易流程:查询目标->行走->攻击,依次循环 ok,在此,我用代码快速模拟这样一个情景,建立一个Hero类,如下: using UnityEngine; using System.Collections; using System.Collections.Generic; using System;

// 英雄角色 public class Hero : MonoBehaviour { //当前目标id public int TargetID=0; public List ListMonster; void Start() { InvokeRepeating("selectTarget", 0.3f, 0.3f); } // 查询目标 private void selectTarget() { if (TargetID==0) { if (ListMonster.Count > 0) { for (int i = 0; i <= ListMonster.Count; i++) { TargetID = ListMonster[i];[/i] WalkToTarget(TargetID);

你可能不知道的陷阱:C#委托和事件的困惑

你可能不知道的陷阱:C#委托和事件的困惑 . 问题引入 通常,一个C 语言学习者登堂入室的标志就是学会使用了指针,而成为高手的标志又是“玩转指针”。指针是如此奇妙,通过一个地址,可以指向一个数,结构体,对象,甚至函数。最后的一种函数,我们称之为“函数指针”(和“指针函数”可不一样!)就像如下的代码: 1 2 3 int func(int x); /* 声明一个函数 */ int (*f) (int x); /* 声明一个函数指针 */ f=func; /* 将func 函数的首地址赋给指针f */ C 语言因为函数指针获得了极强的动态性,因为你可以通过给函数指针赋值并动态改变其行为,我曾在单片机上写的一个小系统中,任务调度机制玩的就是函数指针。 在.NET 时代,函数指针有了更安全更优雅的包装,就是委托。而事件,则是为了限制委托灵活性引入的新“委托”(之所以为什么限制,后面会谈到)。同样,熟练掌握委托和事件,也是C#登堂入室的标志。有了事件,大大简化了编程,类库变得前所未有的开放,消息传递变得更加简单,任何熟悉事件的人一定都深有体会。 但你也知道,指针强大,高性能,带来的就是危险,你不知道这个指针是否安全,出了问题,非常难于调试。事件和委托这么好,可是当你写了很多代码,完成大型系统时,心里是不是总觉得怪怪的?有当年使用指针时类似的感觉? 如果是的话,请看如下的问题: 1. 若多次添加同一个事件处理函数时,触发时处理函数是否也会多次触发? 2. 若添加了一个事件处理函数,却执行了两次或多次”取消事件“,是否会报错? 3. 如何认定两个事件处理函数是一样的? 如果是匿名函数呢? 4. 如果不手动删除事件函数,系统会帮我们回收吗? 5. 在多线程环境下,挂接事件时和对象创建所在的线程不同,那事件处理函数中的代码将在哪个线程中执行? 6. 当代码的层次复杂时,开放委托和事件是不是会带来更大的麻烦? 列下这些问题,下面就让我们讨论这些”尖酸刻薄“的问题。 二. 事件订阅和取消问题 我们考虑一个典型的例子:加热器,加热器内部加热,在达到温度后通知外界”加热已经完成“。 尝试写下如下测试类:

C#委托、事件、自定义事件的理解

C#委托、事件、自定义事件的理解 一、委托 委托类似于函数指针,但函数指针只能引用静态方法,而委托既能引用静态方法,也能引用实例方法。委托使用分三步:1、委托声明。2、委托实例化。3、委托调用。 例程一: using System; namespace 委托 { delegate int NumOpe(int a,int b); //委托声明 class Class1 { static void Main(string[] args) { Class1 c1 = new Class1(); NumOpe p1 = new NumOpe(c1.Add); //委托实例化 Console.WriteLine(p1(1,2)); //委托调用 Console.ReadLine(); } private int Add(int num1,int num2) { return(num1+num2); } } } 例中,委托NumOpe引用了方法Add。 委托声明了以后,就可以象类一样进行实例化,实例化时把要引用的方法(如:Add)做为参数,这样委托和方法就关联了起来,就可以用委托来引用方法了。 委托和所引用的方法必须保持一致: 1)参数个数、类型、顺序必须完全一致。2)返回值必须一致。 二、事件 事件有很多,比如说鼠标的事件:MouserMove,MouserDown等,键盘的事件:KeyUp,KeyDown,KeyPress。 有事件,就会有对事件进行处理的方法,而事件和处理方法之间是怎么联系起来的呢?委托就是他们中间的桥梁,事件发生时,委托会知道,然后将事件传递给处理方法,处理方法进行相应处理。

C#委托与事件

我们抛弃各种C#参考书中桀骜难懂的事件与委托概念,设想一个情景来理解事件与委托的使用:有一家IT公司,董事长不希望自己的雇员在上班时间玩游戏,但又不可能每时每刻都盯着每个雇员,因此,他希望使用一种新的方式实现监视雇员的效果:如果有雇员违反规定,某个设备或专门的监查人员将自动发出一个消息通知他,董事长只需要在事情发生时进行处理。 因此,这个用例实际上是两种类型——董事长类与雇员类——之间的交互,下面的代码将给读者展示如何使用委托与事件机制实现这种交互: 首先,我们需要在董事长类与雇员类之间定义一个委托类型,用于传递两者之间的事件,这个类型就是一个监视设备或专门负责打小报告的监查人员: public delegate void DelegateClassHandle(); 定义一个委托的过程类似方法的定义,但它没有方法体。定义委托一定要添加关键字delegate。由于定义委托实际上相当一个类,因此可以在定义类的任何地方定义委托。另外,根据委托的可见性,也可以添加一般的访问修饰符,如public、private和protected。 委托的返回值类型为void,这并非表示委托类型本身带有返回值,该返回值类型是指委托的目标函数类型,即它委托的一个事件处理函数返回值是void类型。 新建一个雇员类Employee,其代码如下: public class Employee { public event DelegateClassHandle PlayGame; public void Games() { if (PlayGame != null) { PlayGame(); } } } 雇员类Employee代码中定义了一个DelegateClassHandle类型的事件PlayGame,它的定义方式也很特殊,首先必须使用关键字event,表示PlayGame是一个事件,同时还必须声明该事件的委托类型为DelegateClassHandle,即将来由该类型的委托对象负责通知事件。 如果有雇员开始玩游戏,它将执行Games方法,而只要该方法一被调用,就会触发一个事件PlayGame,然后董事长就会收到这个事件的消息——有人在玩游戏了。 董事长类代码如下,他有一个方法Notify用于接收消息: public class Admin { public void Notify() {

c#中如何深入理解“事件与委托”

C#中如何深入理解“事件与委托”?(初学者必看) 2008年01月19日星期六 22:57 事件与委托似乎很难以理解,这是因为它们的使用方式与常用的编码有很大的差别,例如通常编写的都是同步代码,调用一个类型的方法,会即刻出现方法执行的结果,这是符合逻辑的。但在某些情况中,同步代码未必满足需求,拿公共汽车来打个比方,如果交通管制中心希望每一辆公车到达一个站点时都发送给自己一个信号以便自己能够随时掌握交通状况,使用同步代码,公汽对象肯定需要调用管制中心对象,这样就出现了我们一直不愿意看到的情况:两个类型紧密地耦合在一起。既然要其它类型对自己的行为作出反应,亲自调用其类型的方法似乎不可避免,在同步代码中,很难避免这种紧密的类型调用关系。 另一个差别是在一般情况下,我们只将属性作为参数传递给方法,而很少会考虑将一个方法传递给另一个方法。 我们抛弃各种C#参考书中桀骜难懂的事件与委托概念,设想一个情景来理解事件与委托的使用:有一家IT公司,董事长不希望自己的雇员在上班时间玩游戏,但又不可能每时每刻都盯着每个雇员,因此,他希望使用一种新的方式实现监视雇员的效果:如果有雇员违反规定,某个设备或专门的监查人员将自动发出一个消息通知他,董事长只需要在事情发生时进行处理。 因此,这个用例实际上是两种类型——董事长类与雇员类——之间的交互,下面的代码将给读者展示如何使用委托与事件机制实现这种交互: 首先,我们需要在董事长类与雇员类之间定义一个委托类型,用于传递两者之间的事件,这个类型就是一个监视设备或专门负责打小报告的监查人员: public delegate void DelegateClassHandle(); 定义一个委托的过程类似方法的定义,但它没有方法体。定义委托一定要添加关键字delegate。由于定义委托实际上相当一个类,因此可以在定义类的任何地方定义委托。另外,根据委托的可见性,也可以添加一般的访问修饰符,如public、private和protected。 委托的返回值类型为void,这并非表示委托类型本身带有返回值,该返回值类型是指委托的目标函数类型,即它委托的一个事件处理函数返回值是void类型。 新建一个雇员类Employee,其代码如下: public class Employee { public event DelegateClassHandle PlayGame; public void Games() { if (PlayGame != null) { PlayGame(); } } }

委托和事件的区别

委托和事件的区别(讲的很详细)--转 委托和事件在 .Net Framework中的应用非常广泛,然而,较好地理解委托和事件对很多接触C#时间不长的人来说并不容易。它们就像是一道槛儿,过了这个槛的人,觉得真是太容易了,而没有过去的人每次见到委托和事件就觉得心里别(biè)得慌,混身不自在。本文中,我将通过两个范例由浅入深地讲述什么是委托、为什么要使用委托、事件的由来、.Net Framework中的委托和事件、委托和事件对Observer设计模式的意义,对它们的中间代码也做了讨论。 将方法作为方法的参数 我们先不管这个标题如何的绕口,也不管委托究竟是个什么东西,来看下面这两个最简单的方法,它们不过是在屏幕上输出一句问候的话语: public void GreetPeople(string name) { // 做某些额外的事情,比如初始化之类,此处略 EnglishGreeting(name); } public void EnglishGreeting(string name) { Console.WriteLine("Morning, " + name); } 暂且不管这两个方法有没有什么实际意义。GreetPeople用于向某人问好,当我们传递代表某人姓名的name参数,比如说“Jimmy”,进去的时候,在这个方法中,将调用EnglishGreeting方法,再次传递name参数,EnglishGreeting则用于向屏幕输出“Morning, Jimmy”。 现在假设这个程序需要进行全球化,哎呀,不好了,我是中国人,我不明白“Morning”是什么意思,怎么办呢?好吧,我们再加个中文版的问候方法: public void ChineseGreeting(string name){ Console.WriteLine("早上好, " + name); } 这时候,GreetPeople也需要改一改了,不然如何判断到底用哪个版本的Greeting问候方法合适呢?在进行这个之前,我们最好再定义一个枚举作为判断的依据: public enum Language{ English, Chinese } public void GreetPeople(string name, Language lang){ //做某些额外的事情,比如初始化之类,此处略 swith(lang){ case Language.English:

委托与事件的区别

委托与事件的区别 委托和事件在 .Net Framework中的应用非常广泛,然而,较好地理解委托和事件对很多接触C# 时间不长的人来说并不容易。它们就像是一道槛儿,过了这个槛的人,觉得真是太容易了,而没 有过去的人每次见到委托和事件就觉得心里别(biè)得慌,混身不自在。本文中,我将通过两个 范例由浅入深地讲述什么是委托、为什么要使用委托、事件的由来、.Net Framework中的委托和 事件、委托和事件对Observer设计模式的意义,对它们的中间代码也做了讨论。 将方法作为方法的参数 我们先不管这个标题如何的绕口,也不管委托究竟是个什么东西,来看下面这两个最简单的方法,它们不过是在屏幕上输出一句问候的话语: public void GreetPeople(string name) { // 做某些额外的事情,比如初始化之类,此处略 EnglishGreeting(name); } public void EnglishGreeting(string name) { Console.WriteLine("Morning, " + name); } 暂且不管这两个方法有没有什么实际意义。GreetPeople用于向某人问好,当我们传递代表某人姓 名的name参数,比如说“Jimmy”,进去的时候,在这个方法中,将调用EnglishGreeting方法,再 次传递name参数,EnglishGreeting则用于向屏幕输出“Morning, Jimmy”。 现在假设这个程序需要进行全球化,哎呀,不好了,我是中国人,我不明白“Morning”是什么意思,怎么办呢?好吧,我们再加个中文版的问候方法: public void ChineseGreeting(string name){ Console.WriteLine("早上好, " + name); } 这时候,GreetPeople也需要改一改了,不然如何判断到底用哪个版本的Greeting问候方法合适呢?在进行这个之前,我们最好再定义一个枚举作为判断的依据: public enum Language{ English, Chinese }

C中的委托的使用和讲解

C#中的委托引言 委托和事件在.NetFramework中的应用非常广泛,然而,较好地理解委托和事件对很多接触C#时间不长的人来说并不容易。它们就像是一道槛儿,过了这个槛的人,觉得真是太容易了,而没有过去的人每次见到委托和事件就觉得心里别(biè)得慌,混身不自在。本文中,我将通过两个范例由浅入深地讲述什么是委托、为什么要使用委托、事件的由来、.NetFramework中的委托和事件、委托和事件对Observer设计模式的意义,对它们的中间代码也做了讨论。 将方法作为方法的参数 我们先不管这个标题如何的绕口,也不管委托究竟是个什么东西,来看下面这两个最简单的方法,它们不过是在屏幕上输出一句问候的话语: 1publicvoid GreetPeople(string name){ 2//做某些额外的事情,比如初始化之类,此处略 3EnglishGreeting(name); 4} 1publicvoid EnglishGreeting(string name){ 2Console.WriteLine("Morning,"+name); 3} 暂且不管这两个方法有没有什么实际意义。GreetPeople用于向某人问好,当我们传递代表某人姓名的name参数,比如说“JiYF”,进去的时候,在这个方法中,将调用EnglishGreeting方法,再次传递name参数,EnglishGreeting则用于向屏幕输出“Morning,JiYF”。 现在假设这个程序需要进行全球化,哎呀,不好了,我是中国人,我不明白“Morning”是什么意思,怎么办呢?好吧,我们再加个中文版的问候方法: 1publicvoid ChineseGreeting(string name){ 2Console.WriteLine("早上好,"+name); 3} 这时候,GreetPeople也需要改一改了,不然如何判断到底用哪个版本的Greeting 问候方法合适呢?在进行这个之前,我们最好再定义一个枚举作为判断的依据: 1publicenum Language{ 2English,Chinese 3} 1publicvoid GreetPeople(string name,Languagelang){ 2//做某些额外的事情,比如初始化之类,此处略 3swith(lang){

从一则案例看行政委托与行政授权的区别

(https://www.360docs.net/doc/937813937.html,) 从一则案例看行政委托与行政授权的区别 一、一则案例的引出 2013年4月26日,原告饶某以特快专递的方式向被告临川区温泉镇人民政府邮寄了政府信息公开的申请,其申请事项为:请求被告公开2010年、 2011年、2012年温泉镇人民政府每年征收的社会抚养费总数及用途。被告于2013年4月28日收到了原告的政府信息公开申请书,但是超过法定期限未予答复。原告遂依据相关的法律规定向法院提起行政诉讼。 被告辩称:原告饶某诉请公布社会抚养费的征收情况与其没有法律上的利害关系,其不具有提起行政诉讼的主体资格。社会抚养费的征收机关是当地计划生育行政部门,被告温泉镇人民政府是受委托的机关,不存在直接向原告饶某公开社会抚养费的征收情况,原告诉请的对象错误,被告主体不适格。 被告是否具有向原告履行政府信息公开的法定职责,取决于被告的诉讼主体是否适格。行政委托不同于行政授权,被告如果是受委托行政机关,就不具有诉讼主体资格。本案存在的主要问题是被告主体是否适格的问题。行政委托案件中,被告应是行使委托的行政机关。 二、行政委托与行政授权的区别 (一)行政委托的概念与构成要件 行政委托是指行政机关将其管辖权的一部分交由行政机关之外的组织或者个人,并以委托机关的名义行使行政职能。从广义上讲,行政机关之间的委托也应当包括在内。 行政委托的法律要件包括以下四个方面的内容: 1、委托必须有法定依据。行政机关必须在法律、法规及规章规定可以委托时,才能委托。没有法定依据的委托,叫做…自行委托?,是不合法的,也是无效的。 2、委托行政机关必须拥有法定权限。委托机关在进行行政委托时,其委托给受委托人的公权力必须是其自身合法拥有的职权。如果行政机关把一项本身不拥有的公权力委托给受委托人行使,这显然是滥用职权,超越权限的委托当然无效。

委托与事件代码详解与(Object_sender,EventArgs_e)详解

1 委托与事件代码详解与(Object sender,EventArgs e )详解 using System; using System.Collections.Generic; using System.Text; namespace @Delegate //自定义命名空间,新建控制台程序,命名后自动添加 { // 热水器 public class Heater { private int temperature; public string type = "RealFire 001"; // 添加型号作为演示 public string area = "China Xian"; // 添加产地作为演示 //声明委托 public delegate void BoiledEventHandler(Object sender, BoiledEventArgs e);/*BoiledEventHandler 相当于一个类型(属于委托),与String 地位等同,它所声明的参数形式与后来它要包含的方法的参数形式必须是一致的,例如黄色加亮部分的方法*/ public event BoiledEventHandler Boiled; /*声明事件。相当于封装BoiledEventHandler 类型的对象(变量) Boiled ,使之在类的内部总是pravite 的,而使+=和-=的访问权限为声明时的修饰符权限*/ // 定义BoiledEventArgs 类,传递给Observer 所感兴趣的信息。//Observer 设计模式 public class BoiledEventArgs : EventArgs { public readonly int temperature; public BoiledEventArgs(int temperature) { this.temperature = temperature; } } // 可以供继承自 Heater 的类重写,以便继承类拒绝其他对象对它的监视//虚方法可以在类中覆盖重写 protected virtual void OnBoiled(BoiledEventArgs e) { if (Boiled != null) { // 如果有对象注册 Boiled(this, e); // 调用所有注册对象的方法 } } // 烧水。 public void BoilWater() { for (int i = 0; i <= 100; i++) {

委托和事件的直接理解

初学者在理解委托和事件时常常被msdn搞糊涂,为了让初学.net的人快速应用.net的委托和事件模型编程,我在这里主要是提出理解的关键,以下代码都可直接运行,先看下面的代码。 using System; namespace delegeteTest { class delegeteClass { public delegate void fHandler(int a); //关键-此行可以看成类的声明 public fHandler f0; public void d(int a,int b ) { int c=a+b; f0(c); } } class test { public void output(int mun) { System.Console .WriteLine ("{0}",mun); } [STAThread] static void Main(string[] args) { test t=new test (); delegeteClass dc=new delegeteClass (); dc.f0 =new delegeteTest.delegeteClass.fHandler (t.output);//实例的初始化 dc.d(2,3); } } } 解释一下"关键": 实际上 public delegate void fHandler(int a);可以看成如下: class fHandler {.....} 类内部由编译器自动完成,是一个sealed类通过反汇编可以看到,是一个类的声明,它检查加入自己的函数的信息,如,返回值和参数类型

C委托的妙文让你知道如何发挥委托的作用

C委托的妙文让你知道如何发挥委托的作用 Revised final draft November 26, 2020

委托和事件在 .Net Framework中的应用非常广泛,然而,较好地理解委托和事件对很多接触C#时间不长的人来说并不容易。它们就像是一道槛儿,过了这个槛的人,觉得真是太容易了,而没有过去的人每次见到委托和事件就觉得心里别 (biè)得慌,混身不自在。本文中,我将通过两个范例由浅入深地讲述什么是委托、为什么要使用委托、事件的由来、.Net Framework中的委托和事件、委托和事件对Observer设计模式的意义,对它们的中间代码也做了讨论。 将方法作为方法的参数 我们先不管这个标题如何的绕口,也不管委托究竟是个什么东西,来看下面这两个最简单的方法,它们不过是在屏幕上输出一句问候的话语: 以下为引用的内容: public void GreetPeople(string name) { // 做某些额外的事情,比如初始化之类,此处略 EnglishGreeting(name); } public void EnglishGreeting(string name) { Conso le.WriteLine(”Morning, ” name); } 暂且不管这两个方法有没有什么实际意义。GreetPeople用于向某人问好,当我们传递代表某人姓名的name参数,比如说“Jimmy”,进去的时候,在这个方法中,将调用EnglishGreeting方法,再次传递name参数,EnglishGreeting则用于向屏幕输出“Morning, Jimmy”。 现在假设这个程序需要进行全球化,哎呀,不好了,我是人,我不明白“Morning”是什么意思,怎么办呢?好吧,我们再加个中文版的问候方法: 以下为引用的内容: public void ChineseGreeting(string name){ Console.WriteLine(”早上好, ” name); } 这时候,GreetPeople也需要改一改了,不然如何判断到底用哪个版本的Greeting 问候方法合适呢?在进行这个之前,我们最好再定义一个枚举作为判断的依据:以下为引用的内容: view plaincopy to clipboardprint? 1. public enum Language{ 2. English, Chinese 3. }

相关文档
最新文档