C#事件相关 论坛里找了几个关于事件的例子 逐句调试时的顺序没看懂

qq_43492377 2020-07-12 09:14:26
下面例子里
在EventTest e = new EventTest()这个实例化里
调用顺序是public EventTest()→public void SetValue(int n)→protected virtual void OnNumchanged()→public EventTest()→public void SetValue(int n)。为什么是先public void SetValue(int n)开始,后面2个方法调2次?感觉事件还是没怎么掌握

using System;
namespace SimpleEvent
{
using System;
/***********发布器类***********/
public class EventTest
{
private int value;

public delegate void NumManipulationHandler();


public event NumManipulationHandler ChangeNum;
protected virtual void OnNumChanged()
{
if ( ChangeNum != null )
{
ChangeNum(); /* 事件被触发 */
}else {
Console.WriteLine( "event not fire" );
Console.ReadKey(); /* 回车继续 */
}
}


public EventTest()
{
int n = 5;
SetValue( n );
}


public void SetValue( int n )
{
if ( value != n )
{
value = n;
OnNumChanged();
}
}
}


/***********订阅器类***********/

public class subscribEvent
{
public void printf()
{
Console.WriteLine( "event fire" );
Console.ReadKey(); /* 回车继续 */
}
}

/***********触发***********/
public class MainClass
{
public static void Main()
{
EventTest e = new EventTest(); /* 实例化对象,第一次没有触发事件 */
subscribEvent v = new subscribEvent(); /* 实例化对象 */
e.ChangeNum += new EventTest.NumManipulationHandler( v.printf ); /* 注册 */
e.SetValue( 7 );
e.SetValue( 11 );
}
}
}
...全文
5579 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
正怒月神 2020-07-14
  • 打赏
  • 举报
回复
首先
public void SetValue( int n )
    {
      if ( value != n )
      {
        value = n;
        OnNumChanged();
      }
    }
本质上是一个属性封装。通过名字也能理解了。 而SetValue代表属性变更,当属性变更时,调用了OnNumChanged方法。 OnNumChanged内部又是一个事件ChangeNum 重点就是ChangeNum事件, 其实是在 e.ChangeNum += new EventTest.NumManipulationHandler( v.printf ); 注册的。
jmllc 2020-07-14
  • 打赏
  • 举报
回复
引用 8 楼 jmllc 的回复:
C#写关于事件的代码,需要检查几个要件: 一、委托(中立的第三方): 1.委托声明;.net提供了很多可用的、好用的委托,比如:System.EventHandler。当然也可以自己声明委托,在这里你自己进行了委托声明:NumManipulationHandler。 二、事件(乙方): 2.事件声明:用event关键字声明的与委托关联的声明,或者可以理解为:为类对象定义一个“事件”,供他人订阅事件。在这里是ChangeNum:public event NumManipulationHandler ChangeNum; 3.内部事件触发:一般声明为private或protected,他人不可调用,常见的是以on为开头的函数,函数体内容有固定的套路。基本上需要实现的功能是:为回调函数提供参数(如果有参数的话),并调用回调函数。在这里是OnNumChanged()。 4.对外开放的、供他人调用的事件触发函数。在这里是SetValue()和EventTest()。 三、事件的订阅(甲方) 5.事件的订阅:将事件关联到一个回调函数。在这里是:e.ChangeNum += new EventTest.NumManipulationHandler(v.printf); 6.调用触发事件的函数:在这里是e.SetValue(7);e.SetValue(11); 在这里,作为甲方的MainClass.Main函数,调用乙方提供的服务,可以通过乙方公开的事件触发函数:SetValue()和EventTest()。所以,这里e.SetValue(7);e.SetValue(11);是正确的。而通过e.EventTest()。
是构造函数。在e被构造时,e.ChangeNum += new EventTest.NumManipulationHandler(v.printf); 并没有被执行,所以OnNumChanged()中if判断为假,v.printf并不会被执行。
jmllc 2020-07-13
  • 打赏
  • 举报
回复
C#写关于事件的代码,需要检查几个要件: 一、委托(中立的第三方): 1.委托声明;.net提供了很多可用的、好用的委托,比如:System.EventHandler。当然也可以自己声明委托,在这里你自己进行了委托声明:NumManipulationHandler。 二、事件(乙方): 2.事件声明:用event关键字声明的与委托关联的声明,或者可以理解为:为类对象定义一个“事件”,供他人订阅事件。在这里是ChangeNum:public event NumManipulationHandler ChangeNum; 3.内部事件触发:一般声明为private或protected,他人不可调用,常见的是以on为开头的函数,函数体内容有固定的套路。基本上需要实现的功能是:为回调函数提供参数(如果有参数的话),并调用回调函数。在这里是OnNumChanged()。 4.对外开放的、供他人调用的事件触发函数。在这里是SetValue()和EventTest()。 三、事件的订阅(甲方) 5.事件的订阅:将事件关联到一个回调函数。在这里是:e.ChangeNum += new EventTest.NumManipulationHandler(v.printf); 6.调用触发事件的函数:在这里是e.SetValue(7);e.SetValue(11); 在这里,作为甲方的MainClass.Main函数,调用乙方提供的服务,可以通过乙方公开的事件触发函数:SetValue()和EventTest()。所以,这里e.SetValue(7);e.SetValue(11);是正确的。而通过e.EventTest()。
qq_43492377 2020-07-13
  • 打赏
  • 举报
回复
实例化对象的时候先构造器是入口所以先SetValue!?我想我应该是这里没弄清楚
  • 打赏
  • 举报
回复
在实际写一个“小”程序时,一般人用不到事件。自己创建一个对象,然后抛出事件,让自己实现向这个对象注册的事件处理过程来捕获通知进行处理,自己绕自己,看上去会比较累赘。所以这类是初学者难以理解的。当你有多人协作的思想,不同系统分多个阶段、多人、多个项目开发协同的思想,有一些“工程”经验,了解面向接口和模式进行设计的根源,才会逐步熟悉基本架构知识的重要性。各种编程方法定义可以随时上网去查,根本没有必要记住。但是具体产品的工程架构设计,在网上查不到,别人也不不会讲。许多初学者把只费你 15% 的经理的知识以为是软件的全部,而不清楚绝大部分的技术都是没办法从网上直接抄到的,自己越早打下工程基础越好。
  • 打赏
  • 举报
回复
引用 楼主 qq_43492377 的回复:
为什么是先public void SetValue(int n)开始,后面2个方法调2次

最初步的东西是基本语法,语法可以滥竽充数,但是软件工程的东西则难以滥竽充数。对于开发人员来说,编程中要知道基本语法和方法定义,占5%,而 95%的能力来自于对于流程和模式的理解过程。理解一个“系统设计”可以通过借助隐喻,系统设计往往是前人“搭好框架”,而“后来的人”能够仅提供扩展的一些差别细节而无需重复写代码。如果后来人没认真学习那些本来是不希望其重写的代码,实际上这样的后来人就像是流水线上的临时工,或者像是炮灰。但是如果一个工人他能自己猜想系统设计图,就不一样了。

事件是最基本的程序“流程驱动”模式。就好像你去许多公司应聘,然后人家会告诉你说“等通知,我随后会联系你”。你无需去阻塞人家的工作,你也不知道各个公司会以什么顺序通知你。但是人家通知你之后,你就可以继续自己的下一步计划。

所以要了解事件,你必须去想象一下人家的引擎的基本流程,了解人家的系统设计思路。人家觉得有必要通知你的时候,才会触发事件来通知你,让你动起来。这就是事件。
八爻老骥 2020-07-12
  • 打赏
  • 举报
回复
第一次SetValue,事件还空的。注册事件后再SetValue当然有值了。
  • 打赏
  • 举报
回复
你在回调函数里输出setvalue设置的值,结果应该是5,7,11。执行顺序没错。

110,533

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧