深入解析C#编程中的事件

网上科普有关“深入解析C#编程中的事件”话题很是火热,小编也是针对深入解析C#编程中的事件寻找了一些与之相关的一些信息进行分析,如果能碰巧解决你现在面临的问题,希望能够帮助到您...

网上科普有关“深入解析C#编程中的事件”话题很是火热,小编也是针对深入解析C#编程中的事件寻找了一些与之相关的一些信息进行分析,如果能碰巧解决你现在面临的问题,希望能够帮助到您。

 一个事件是一个使对象或类可以提供公告的成员 用户可以通过提供事件句柄来为事件添加可执行代码 事件使用事件声明来声明 一个事件声明既可以是一个事件域声明也可以是事件属性声明 在每种情况中 声明都可以由属性集合 new 修饰符 四个访问修饰符的有效组合 和一个静态修饰符组成 一个事件声明的类型必须是一个代表类型 而那个代表类型必须至少同事件本身一样可访问 一个事件域声明与一个声明了一个或多个代表类型域的域声明相应 在一个事件域声明中不允许有readonly 修饰符 一个事件属性声明与声明了一个代表类型属性的属性声明相应 除了同时包含get访问符和set访问符的事件属性声明 成员名称和访问符声明对于那些属性声明来说都是相同的 并且不允许包含virtual override和abstract 修饰符 在包含一个事件成员声明的类或结构的程序文字中 事件成员与代表类型的私有域或属性相关 而这个成员可以用于任何允许使用域或属性的上下文中 如果一个类或结构的程序文字外面包含一个事件成员声明 这个事件成员就只能被作为+= 和 = 操作符 (§的右手操作数使用 这些操作符被用来为事件成员附加或去掉事件句柄 而这个事件成员的访问操作符控制操作在其中被执行的上下文 由于+= 和 = 是唯一可以在声明了事件成员的类型外的事件上使用的操作 外部代码可以为一个事件添加或去掉句柄 但是不能通过任何其他途径获得或修改基本事件域或事件属性的数值 在例子中 public delegate void EventHandler(object sender Event e);public class Button: Control{ public event EventHandler Click; protected void OnClick(Event e) {if (Click != null) Click(this e); } public void Reset() {Click = null; }}对使用Button类中的Click事件域没有限制 作为演示的例子 这个域可以在代表调用表达式中被检验 修改和使用 类Button中的OnClick方法 引起 Click事件 引起一个事件的概念与调用由事件成员表示的代表正好相同-因此 对于引起事件没有特殊的语言构造 注意代表的调用是通过检查保证代表是非空后才进行的 在类Button的声明外面 成员Click只能被用在+= 和 = 操作符右手边 如下 b Click += new EventHandler( );它把一个代表附加到事件Click的调用列表中 并且 b Click = new EventHandler( );

 它把一个代表从Click事件的调用列表中删除 在一个形式为x += y 或 x = y的操作中 当x是一个事件成员而引用在包含x的声明的类型外面发生时 操作的结果就是void(在赋值后与x的数值相反) 这个规则禁止外部代码直接检查事件成员的基本代表

 下面的例子介绍了事件句柄如何附加到上面的类Button的实例中

  public class LoginDialog: Form{ Button OkButton; Button CancelButton; public LoginDialog() {OkButton = new Button( );OkButton Click += new EventHandler(OkButtonClick);CancelButton = new Button( );CancelButton Click += new EventHandler(CancelButtonClick); } void OkButtonClick(object sender Event e) {// Handle OkButton Click event } void CancelButtonClick(object sender Event e) {// Handle CancelButton Click event }}这里 构造函数LoginDialog创建了两个Button实例 并且把事件句柄附加到事件Click中 事件成员是典型域 就像上面的Button例子中所示 在每个事件消耗一个域存储的情况是不可接受的 一个类可以声明事件属性来替代事件域 并且使用私有机制来存储基本的代表 (设想在某种情况下 大多数事件都是未处理的 每个事件使用一个域就不能被接受 使用属性而不是域的能力允许开发人员在空间和时间上面取得一个折中方案 )在例子中 class Control: Component{ // Unique keys for events static readonly object mouseDownEventKey = new object(); static readonly object mouseUpEventKey = new object(); // Return event handler associated with key protected Delegate GetEventHandler(object key) { } // Set event handler associated with key protected void SetEventHandler(object key Delegate handler) { } // MouseDown event property public event MouseEventHandler MouseDown {get { return (MouseEventHandler)GetEventHandler(mouseDownEventKey);}set { SetEventHandler(mouseDownEventKey value);} } // MouseUp event property public event MouseEventHandler MouseUp {get { return (MouseEventHandler)GetEventHandler(mouseUpEventKey);}set { SetEventHandler(mouseUpEventKey value);}}}

 类Control为事件提供了一种内部存储机制 方法SetEventHandler用一个key来与代表数值相关 而方法GetEventHandler返回与key相关的当前代表 大概基本的存储机制是按照把空代表类型与key相关不会有消耗而设计的 因此无句柄的事件不占用存储空间

实例变量初始化函数 当一个构造函数没有构造初始化函数或一个形式为base( )的构造函数初始化函数 构造函数就就隐含的执行被类中声明的实例域的变量初始化函数指定的初始化 这与赋值序列相关 这些赋值在直接基类构造函数的隐式调用前 在构造函数的入口被直接执行 变量初始化函数按照它们在类声明中出现的文字顺序执行 构造函数执行 可以把一个实例变量初始化函数和一个构造函数初始化函数 看作是自动插在构造函数主体中的第一条语句前 例子

  using System Collections;class A{ int x = y = count; public A() {count = ; } public A(int n) {count = n; }}class B: A{ double sqrt = Math Sqrt( ); ArrayList items = new ArrayList( ); int max; public B(): this( ) {items Add( default ); } public B(int n): base(n ) {max = n; }}

 包含了许多变量初始化函数 并且也包含了每个形式(base和this)的构造函数初始化函数 这个例子与下面介绍的例子相关 在那里 每条注释指明了一个自动插入的语句(自动插入构造函数调用所使用的语法不是有效的 至少用来演示这个机制)

  using System Collections;class A{ int x y count; public A() {x = ; // Variable initializery = ; // Variable initializerobject(); // Invoke object() constructorcount = ; } public A(int n) {x = ; // Variable initializery = ; // Variable initializerobject(); // Invoke object() constructorcount = n; }}class B: A{ double sqrt ; ArrayList items; int max; public B(): this( ) {B( ); // Invoke B(int) constructoritems Add( default ); } public B(int n): base(n ) {sqrt = Math Sqrt( ); // Variable initializeritems = new ArrayList( ); // Variable initializerA(n ); // Invoke A(int) constructormax = n; }}

 注意变量初始化函数被转换为赋值语句 并且那个赋值语句在对基类构造函数调用前执行 这个顺序确保了所有实例域在任何访问实例的语句执行前 被它们的变量初始化函数初始化 例如

  class A{ public A() {PrintFields(); } public virtual void PrintFields() {}}class B: A{ int x = ; int y; public B() {y = ; } public override void PrintFields() {Console WriteLine( x = { } y = { } x y); }}

 当new B() 被用来创建B的实例时 产生下面的输出 x = y =

 因为变量初始化函数在基类构造函数被调用前执行 所以x的数值是 可是 y的数值是 (int的默认数值) 这是因为对y的赋值直到基类构造函数返回才被执行 默认构造函数 如果一个类不包含任何构造函数声明 就会自动提供一个默认的构造函数 默认的构造函数通常是下面的形式

  public C(): base() {}

 这里C是类的名称 默认构造函数完全调用直接基类的无参数构造函数 如果直接基类中没有可访问的无参数构造函数 就会发生错误 在例子中

  class Message{ object sender; string text;}

 因为类不包含构造函数声明 所以提供了一个默认构造函数 因此 这个例子正好等同于

  class Message{ object sender; string text; public Message(): base() {}}

  私有构造函数 当一个类只声明了私有的构造函数时 其他类就不能从这个类派生或创建类的实例 私有构造函数通常用在只包含静态成员的类中 例如

 public class Trig{private Trig() {} // Prevent instantiationpublic const double PI = ;public static double Sin(double x) { }public static double Cos(double x) { }public static double Tan(double x) { }}

Trig 类提供了一组相关的方法和常数 但没有被例示 因此 它声明了一个单独的私有构造函数 注意至少要必须声明一个私有构造函数来避免自动生成默认的构造函数(它通常有公共的访问性) 可选的构造函数参数 构造函数的this( ) 形式通常用于与实现可选的构造函数参数的关联上 在这个例子中 class Text{ public Text(): this( null) {} public Text(int x int y): this(x y null) {} public Text(int x int y string s) {// Actual constructor implementation }}前两个构造函数只是为丢失的参数提供了默认的数值 两个都使用了一个this( )构造函数的初始化函数来调用第三个构造函数 它实际上做了对新实例进行初始化的工作 效果是那些可选的构造函数参数 Text t = new Text(); // Same as Text( null)Text t = new Text( ); // Same as Text( null)Text t = new Text( Hello ); 析构函数 析构函数是一个实现破坏一个类的实例的行为的成员 析构函数使用析构函数声明来声明 一个析构函数声明的标识符必须为声明析构函数的类命名 如果指定了任何其他名称 就会发生一个错误 析构函数声明的主体指定了为了对类的新实例进行初始化而执行的语句 这于一个有void返回类型的实例方法的主体相关 例子 class Test{ static void Main() {A F();B F(); }}class A{ static A() {Console WriteLine( Init A ); } public static void F() {Console WriteLine( A F ); }}class B{ static B() {Console WriteLine( Init B ); } public static void F() {Console WriteLine( B F ); }}会产生或者是下面的输出 Init AA FInit BB F或者是下面的输出 Init BInit AA FB F lishixinzhi/Article/program/net/201311/12463

关于“深入解析C#编程中的事件”这个话题的介绍,今天小编就给大家分享完了,如果对你有所帮助请保持对本站的关注!

本文来自作者[告瑞松]投稿,不代表空气号立场,如若转载,请注明出处:https://haokongqi.org.cn/cshi/202504-921.html

(157)

文章推荐

  • 现在病毒传染情况(我们这次的病毒传染速度究竟有多快)

    今天给各位分享现在病毒传染情况的知识,其中也会对我们这次的病毒传染速度究竟有多快进行解释,如果能碰巧解决你现在面临的问题,别忘了关注本站,现在开始吧!新型冠状病毒传染途径是什么?接触传播:新型冠状病毒可以通过接触被病毒污染的物体表面后,再触摸自己的口、鼻或眼睛而传播。飞沫传播:这是新型冠状病毒传

    2025年03月01日
    25
  • 疫情疫苗种类有几种(疫情疫苗种类有几种类型)

    今天给各位分享疫情疫苗种类有几种的知识,其中也会对疫情疫苗种类有几种类型进行解释,如果能碰巧解决你现在面临的问题,别忘了关注本站,现在开始吧!三种新冠疫苗的区别及安全性制备工艺不同灭活疫苗是直接将病毒灭活,使其不具备传染性但能引起免疫应腺病毒载体疫苗是通过基因重组,达到免疫作用。重组亚单位疫苗是

    2025年03月02日
    16
  • 实测教程“疯狂四川麻将老是输(中国象棋)

    网上科普有关“疯狂四川麻将老是输”话题很是火热,小编也是针对疯狂四川麻将老是输寻找了一些与之相关的一些信息进行分析,如果能碰巧解决你现在面临的问题,希望能够帮助到您。  您好,疯狂四川麻将老是输这款游戏可以开挂的,确实是有挂的,通过微信【游戏】很多玩家在这款游戏中打牌都会发现很多用户的牌特别

    2025年03月03日
    12
  • 实测教程“老友麻将怎么开挂(进制转换器)

    网上科普有关“老友麻将怎么开挂”话题很是火热,小编也是针对老友麻将怎么开挂寻找了一些与之相关的一些信息进行分析,如果能碰巧解决你现在面临的问题,希望能够帮助到您。  您好,老友麻将怎么开挂这款游戏可以开挂的,确实是有挂的,通过微信【游戏】很多玩家在这款游戏中打牌都会发现很多用户的牌特别好,总

    2025年03月04日
    11
  • 分享干货”奔驰宝马怎么打才能赢”果然有挂

    分享干货”奔驰宝马怎么打才能赢网上科普有关“分享干货”奔驰宝马怎么打才能赢”话题很是火热,小编也是针对分享干货”奔驰宝马怎么打才能赢寻找了一些与之相关的一些信息进行分析,如果能碰巧解决你现在面临的问题,希望能够帮助到您。  您好,分享干货”奔驰宝马怎么打才能赢这款游戏可以开挂的,确实

    2025年03月07日
    9
  • 修辞手法有哪些种

    网上科普有关“修辞手法有哪些种”话题很是火热,小编也是针对修辞手法有哪些种寻找了一些与之相关的一些信息进行分析,如果能碰巧解决你现在面临的问题,希望能够帮助到您。常见的修辞手法有以下几种:1、比喻比喻就是打比方,是用具体的、浅显的、熟悉的、形象鲜明的事物去说明或描写抽象的、深奥的事物。这样可以把事物

    2025年03月13日
    175
  • 收房是先验房还是先收房再验房

    网上科普有关“收房是先验房还是先收房再验房”话题很是火热,小编也是针对收房是先验房还是先收房再验房寻找了一些与之相关的一些信息进行分析,如果能碰巧解决你现在面临的问题,希望能够帮助到您。当然是可以先收房再进行验房的,但是我们提倡的是先验房后收房,这样体现得更谨慎、合理一些,有时更可以做到防患于未然。

    2025年03月24日
    19
  • 疫情解封顺序(疫情解封的时间)

    今天给各位分享疫情解封顺序的知识,其中也会对疫情解封的时间进行解释,如果能碰巧解决你现在面临的问题,别忘了关注本站,现在开始吧!第一次疫情全国解封时间第一轮疫情全国解封时间是在2020年4月8日。根据公开信息查询,疫情最初在2019年11月出现,并于12月底被确认。正式的封城措施是从2020年

    2025年03月13日
    13
  • 重庆疫情最新数据消息今天新增本土(重庆疫情最新新增病例)

    今天给各位分享重庆疫情最新数据消息今天新增本土的知识,其中也会对重庆疫情最新新增病例进行解释,如果能碰巧解决你现在面临的问题,别忘了关注本站,现在开始吧!重庆疫情多少个截至最近的数据,重庆累计确诊的新冠病毒感染人数已经超过了20,000人。这个数字是根据官方发布的最新情况得出的,反映了疫情在该地区

    2025年03月13日
    14
  • 2020疫情开始的第一天(2020疫情开始的第一天是哪一天)

    今天给各位分享2020疫情开始的第一天的知识,其中也会对2020疫情开始的第一天是哪一天进行解释,如果能碰巧解决你现在面临的问题,别忘了关注本站,现在开始吧!新冠肺炎疫情从哪一年开始2019年12月,新冠病毒疫情在中国武汉市首次被报告。2022年12月26日,国家卫生健康委员会将新型冠状病毒肺炎

    2025年03月21日
    19

发表回复

本站作者后才能评论

评论列表(4条)

  • 告瑞松
    告瑞松 2025年04月20日

    我是空气号的签约作者“告瑞松”!

  • 告瑞松
    告瑞松 2025年04月20日

    希望本篇文章《深入解析C#编程中的事件》能对你有所帮助!

  • 告瑞松
    告瑞松 2025年04月20日

    本站[空气号]内容主要涵盖:国足,欧洲杯,世界杯,篮球,欧冠,亚冠,英超,足球,综合体育

  • 告瑞松
    告瑞松 2025年04月20日

    本文概览:网上科普有关“深入解析C#编程中的事件”话题很是火热,小编也是针对深入解析C#编程中的事件寻找了一些与之相关的一些信息进行分析,如果能碰巧解决你现在面临的问题,希望能够帮助到您...