网站开发合同 doc,装饰公司电话,江苏网站建设企业,深圳seo技术一、什么是事件#xff1f; 在C#中,事件(event)是一种特殊的类成员,它允许类或对象通知其他类或对象发生了某些事情。 从语法上看,事件的声明类似于字段,但它们在功能和行为上有一些重要的区别。 从技术角度来说,事件实际上是一个封装了事件订阅和取消订阅功能的委托字段。…
一、什么是事件 在C#中,事件(event)是一种特殊的类成员,它允许类或对象通知其他类或对象发生了某些事情。 从语法上看,事件的声明类似于字段,但它们在功能和行为上有一些重要的区别。 从技术角度来说,事件实际上是一个封装了事件订阅和取消订阅功能的委托字段。当声明一个事件时,编译器会在背后生成一个私有的委托字段,以及公共的添加(add)和移除(remove)访问器方法。 例如事件声明时:
public event EventHandlerTextArgs TextPublish;
编译器实际上会生成类似如下的代码: private EventHandlerTextArgs _textPublish;public event EventHandlerTextArgs TextPublish{add { _textPublish value; }remove { _textPublish - value; }} 这里,_textPublish是一个私有的委托字段,它存储了所有订阅了TextPublish事件的事件处理方法。add和remove访问器方法提供了订阅和取消订阅事件的功能,它们分别对应了和-操作符。 所以,从这个角度来看,事件更像是一个特殊的属性(property),它封装了一个私有的委托字段,并提供了特定的访问方法。 但是,与普通的属性不同,事件有一些特殊的限制: 1. 事件只能在声明它的类内部直接调用。在类外部,只能通过和-操作符来订阅和取消订阅事件,不能直接读取或赋值事件。 2. 事件通常应该是公共的(public),以允许其他类订阅和取消订阅。但是,事件的访问器方法(add和remove)通常应该是私有的或受保护的,以防止在类外部直接调用。 3. 事件通常应该在引发事件的类中声明,而事件处理方法通常应该在订阅事件的类中定义。这体现了事件的发布-订阅模型。 所以,事件是一种特殊的类成员,它结合了字段、属性和方法的某些特性,用于实现事件驱动编程。理解事件的特殊性质,对于正确地使用和管理事件非常重要。 二、实例说明 举例在Form1与Form2中有button1和textbox1。 点击Form1中的button1显示Form2。点击Form2中的button1将Form2中textbox1中的内容发送到Form1中的textbox1中去。 设计用事件来处理。在Form2声明事件变量实行触发与发布。在Form2中进行事件处理与事件订阅。 form2中 public partial class Form2 : Form{public event EventHandlerTextArgs TextPublish;//apublic Form2()//b{InitializeComponent();}private void button1_Click(object sender, EventArgs e)//c{TextPublish?.Invoke(this, new TextArgs(textBox1.Text));//d}}public class TextArgs : EventArgs//e{public string Text;//fpublic TextArgs(string msg)//h{Text msg;}} form1中 public partial class Form1 : Form{public Form1(){InitializeComponent();}private void button1_Click(object sender, EventArgs e){Form2 fr2 new Form2();//ifr2.TextPublish ShowFromForm2;//jfr2.Show();//k}public void ShowFromForm2(object o, TextArgs e)//m{textBox1.Text e.Text;//n}} (1)问a处是定义事件变量如何理解前后没看到它的实例化它在哪儿 答event关键字表示定义一个事件,EventHandlerTextArgs是事件的委托类型,其中TextArgs是自定义的事件参数类。EventHandlerT中第一个参数固定为object,表示事件的发送者,第二个参数为T类型,是事件的参数。TextPublish是这个事件的名字。事件的定义必须在类内部,因为它是类的成员。 public event EventHandlerTextArgs TextPublish;这行代码只是声明了一个事件,但并没有实例化。它类似于string a;,只是声明了一个字段,但没有给它赋值。 在C#中,事件的声明类似于字段,但又有一些不同。事件声明后,编译器会自动生成一个私有的委托字段来存储事件的处理程序,并生成add和remove访问器来添加或移除事件处理程序。所以我们可以直接使用和-操作符来订阅和取消订阅事件。 在d处,TextPublish.Invoke(...)能够成功调用,是因为在调用之前,这个事件已经被其他地方的代码订阅了(j处),也就是说有地方使用了TextPublish ...;的语句。如果事件没有被任何地方订阅,那么Invoke调用时,TextPublish的值实际上是null,会抛出NullReferenceException异常。 不必显式地实例化事件。 当其他地方(如Form1)订阅了TextPublish事件时,C#编译器会自动实例化TextPublish事件的委托字段。这个委托字段最初为null,当第一次使用操作符添加事件处理程序时,编译器会创建一个新的委托实例,并将其赋值给这个字段。此后,这个字段就不再为null了。每次使用添加新的事件处理程序,都会创建一个新的委托实例,并将其与现有的委托实例合并。 这个自动实例化的过程是由C#编译器在背后完成的,不需要手动去实例化事件。这也是为什么可以直接使用和-操作符来管理事件订阅的原因。这种设计大大简化了事件的使用,让我们可以专注于事件的订阅和发布,而不需要关心事件的实例化细节。 (2)问b处警告退出时textpublish必须非空是什么意思会有什么后果如何避免 答警告说明在Form2的构造函数退出时,TextPublish事件必须被赋值,不能为null。如果TextPublish为null,在调用事件时会导致NullReferenceException。为避免这个问题,你可以在构造函数中为TextPublish赋一个空的事件处理程序,或者在调用前判断是否为null。 (3)问c处单击方法里面一般不直接发布 答通常在UI事件的处理方法中,如button1_Click,我们一般不直接调用事件的发布方法。而是先进行一些必要的检查和数据准备,然后再发布事件。这是一种良好的编程实践。 (4)问d处的this是引用的form2而不是c中参数object的引发者 答d处的this确实是指代的当前Form2的实例,而不是Click事件的sender参数。因为我们是在Form2内部发布自己的TextPublish事件。 另外d处并不是最佳写法。应改为 private void button1_Click(object sender, EventArgs e){string text textBox1.Text;if (!string.IsNullOrWhiteSpace(text)){OnTextPublish(new TextArgs(text));}}protected virtual void OnTextPublish(TextArgs e){TextPublish?.Invoke(this, e);} 将触发和发布分开写可以提高代码的灵活性和可维护性使代码更易于理解、扩展和修改。例如 在发布事件前,可以进行必要的数据检查和准备工作,如上面的代码检查了文本是否为空。 发布事件的逻辑被封装在一个单独的受保护的虚方法OnTextPublish中,子类可以重写这个方法来添加或修改发布事件的逻辑。 在OnTextPublish中,使用了null条件运算符?.来检查事件是否为null,避免了可能的NullReferenceException。事件发布的方法还可以提供一些额外的处理逻辑例如日志记录、异常处理等。在OnTextPublish方法中可以针对特定的事件进行一些前置或后置处理以增加代码的健壮性和可靠性。 这种模式在.NET的类库中广泛使用,它提供了更好的灵活性、可扩展性和安全性。 (5)问e一般继承事件参数是按照单击事件后面跟e参数一样f处就跟具体的信息由h处构造函数传送过来 答对,自定义事件的参数类一般继承自EventArgs,并添加需要传递的数据作为公共属性,就像TextArgs.Text一样。这些数据在构造函数中初始化,在事件处理程序中使用。 EventHandlerTextArgs说明EventHandlerT预定义的第二个参数必须是EventArgs的派生类,如果自定义的事件参数类不继承EventArgse处),就会产生类型不兼容的错误。所以按照约定,自定义事件参数类都应该直接或间接继承自EventArgs。 也可以不使用继承EventArgs的类型比如EventHandlerstring。然后直接传递一个字符串作为事件参数。这在语法上是允许的。但是,这并不是一个好的实践。 使用EventArgs派生类有三处好处表示这个类是事件参数类、传递多个参数时直接融入多个属性即可、方便自己和他人阅读和维护。所以,即使事件参数只有一个字符串,也建议定义一个继承自EventArgs的类来包装它。 (6)问h处警告使用主构造函数这是什么意思只听说过构造函数没听说过主构造函数 答使用主构造函数警告可能是因为你使用了C# 9.0或更高版本引入的主构造函数特性。主构造函数可以简化类的定义,将构造函数参数直接放在类名后面,省去了单独定义字段的麻烦。不过主构造函数只能有一个,如果定义了主构造函数,就不能再有其他构造函数了。这个警告提示你考虑使用主构造函数语法。 主构造函数允许你在类名后面直接添加构造函数参数,编译器会自动生成对应的私有字段和构造函数。例如: public class Person{public Person(string firstName, string lastName){FirstName firstName;LastName lastName;}public string FirstName { get; }public string LastName { get; }} 可以简写为: public class Person(string FirstName, string LastName){} 主构造函数可以简化类的定义,减少重复代码。 但它也有一些限制,例如只能有一个主构造函数,如果定义了主构造函数就不能再定义其他构造函数等。 传统的构造函数语法更灵活,可以定义多个重载的构造函数,也可以在构造函数中编写更复杂的初始化逻辑。 主构造函数更适合那些简单的、只需要初始化几个属性的类。 对于有默认值的主构造函数还可以这样 public class Person(string FirstName John, string LastName Doe){}
在主构造函数中为参数提供默认值,相当于为属性提供了默认值。如果在创建类的实例时没有提供参数,那么这些属性就会使用默认值。 public class Person(string FirstName John, string LastName Doe){}// 使用默认值Person p1 new Person();Console.WriteLine(${p1.FirstName} {p1.LastName}); // 输出: John Doe// 提供参数Person p2 new Person(Jane, Smith);Console.WriteLine(${p2.FirstName} {p2.LastName}); // 输出: Jane Smith (7)问m处事件的处理该方法需要与a处签名一致 答事件处理方法的签名必须与事件的委托类型匹配。在这个例子中,TextPublish事件的类型是EventHandlerTextArgs,所以事件处理方法ShowFromForm2必须有一个object类型的参数(事件发送者)和一个TextArgs类型的参数(事件参数)。在方法体内,我们可以直接使用事件参数e的属性,如e.Text。 (8)问i处实例化时就自动有了TextPubublish成员通过实现了form2中事件变量的变例化原为null的textpublish得到了showformform2因此不空了。 答当Form2的实例fr2被创建时,它的TextPublish事件字段初始为null。但在下一行代码fr2.TextPublish ShowFromForm2;中,通过操作符,将ShowFromForm2方法订阅到了TextPublish事件。这个操作会导致TextPublish字段被实例化为一个新的委托对象,并将ShowFromForm2方法添加到这个委托对象中。因此,TextPublish不再为null。 (9)问k处用了show。如果用了showdialog()将是模态输出可能还有一个隐患? 答Show方法会以非模态的方式显示Form2,这意味着Form1还可以继续响应用户的交互。而ShowDialog会以模态的方式显示Form2,这意味着在Form2关闭之前,用户不能与Form1交互因此ShowDialog后面的语句可以无法得到Form1的响应。例如 Form2 fr2 new Form2();//i fr2.ShowDialog();//k fr2.TextPublish ShowFromForm2;//j 当k语句执行后因为模态的原因form1将“冻结”无法响应也就无法继续执行j句因此后面点击后事件实际上没有发生因为j句没有执行那么事件就没有实例化是一个null在d处是一个空合并操作为null不会执行后面操作所以没有反应。如果改为TextPublish.Invoke(this, new TextArgs(textBox1.Text));在点击后因为TextPublish为空将出现异常。所以这里最好用show若用showdialog则放在最后。
文章转载自: http://www.morning.itvsee.com.gov.cn.itvsee.com http://www.morning.hmsong.com.gov.cn.hmsong.com http://www.morning.alive-8.com.gov.cn.alive-8.com http://www.morning.sfhjx.cn.gov.cn.sfhjx.cn http://www.morning.knczz.cn.gov.cn.knczz.cn http://www.morning.zrwlz.cn.gov.cn.zrwlz.cn http://www.morning.inheatherskitchen.com.gov.cn.inheatherskitchen.com http://www.morning.pyswr.cn.gov.cn.pyswr.cn http://www.morning.mslhq.cn.gov.cn.mslhq.cn http://www.morning.jlgjn.cn.gov.cn.jlgjn.cn http://www.morning.kqhlm.cn.gov.cn.kqhlm.cn http://www.morning.knmp.cn.gov.cn.knmp.cn http://www.morning.bxdlrcz.cn.gov.cn.bxdlrcz.cn http://www.morning.txmkx.cn.gov.cn.txmkx.cn http://www.morning.ghwdm.cn.gov.cn.ghwdm.cn http://www.morning.qwbht.cn.gov.cn.qwbht.cn http://www.morning.bpcf.cn.gov.cn.bpcf.cn http://www.morning.jklns.cn.gov.cn.jklns.cn http://www.morning.rrxmm.cn.gov.cn.rrxmm.cn http://www.morning.sphft.cn.gov.cn.sphft.cn http://www.morning.ryzgp.cn.gov.cn.ryzgp.cn http://www.morning.ndhxn.cn.gov.cn.ndhxn.cn http://www.morning.leboju.com.gov.cn.leboju.com http://www.morning.qnyf.cn.gov.cn.qnyf.cn http://www.morning.srgsb.cn.gov.cn.srgsb.cn http://www.morning.lfdrq.cn.gov.cn.lfdrq.cn http://www.morning.mgzjz.cn.gov.cn.mgzjz.cn http://www.morning.rhqn.cn.gov.cn.rhqn.cn http://www.morning.xjkr.cn.gov.cn.xjkr.cn http://www.morning.qgfy.cn.gov.cn.qgfy.cn http://www.morning.wmmjw.cn.gov.cn.wmmjw.cn http://www.morning.xrwtk.cn.gov.cn.xrwtk.cn http://www.morning.mjwnc.cn.gov.cn.mjwnc.cn http://www.morning.crqbt.cn.gov.cn.crqbt.cn http://www.morning.wtsr.cn.gov.cn.wtsr.cn http://www.morning.bflws.cn.gov.cn.bflws.cn http://www.morning.qbkw.cn.gov.cn.qbkw.cn http://www.morning.ykgp.cn.gov.cn.ykgp.cn http://www.morning.wmmjw.cn.gov.cn.wmmjw.cn http://www.morning.qnlbb.cn.gov.cn.qnlbb.cn http://www.morning.hymmq.cn.gov.cn.hymmq.cn http://www.morning.ttcmdsg.cn.gov.cn.ttcmdsg.cn http://www.morning.tslxr.cn.gov.cn.tslxr.cn http://www.morning.tklqs.cn.gov.cn.tklqs.cn http://www.morning.mgskc.cn.gov.cn.mgskc.cn http://www.morning.csxlm.cn.gov.cn.csxlm.cn http://www.morning.jzccn.cn.gov.cn.jzccn.cn http://www.morning.pfnlc.cn.gov.cn.pfnlc.cn http://www.morning.rpth.cn.gov.cn.rpth.cn http://www.morning.kwblwbl.cn.gov.cn.kwblwbl.cn http://www.morning.fwdln.cn.gov.cn.fwdln.cn http://www.morning.mdrnn.cn.gov.cn.mdrnn.cn http://www.morning.rzdpd.cn.gov.cn.rzdpd.cn http://www.morning.qxycf.cn.gov.cn.qxycf.cn http://www.morning.wqwbj.cn.gov.cn.wqwbj.cn http://www.morning.nqxdg.cn.gov.cn.nqxdg.cn http://www.morning.bzqnp.cn.gov.cn.bzqnp.cn http://www.morning.gjlml.cn.gov.cn.gjlml.cn http://www.morning.bmrqz.cn.gov.cn.bmrqz.cn http://www.morning.wnkjb.cn.gov.cn.wnkjb.cn http://www.morning.gwwky.cn.gov.cn.gwwky.cn http://www.morning.tbhf.cn.gov.cn.tbhf.cn http://www.morning.lgznc.cn.gov.cn.lgznc.cn http://www.morning.zdsqb.cn.gov.cn.zdsqb.cn http://www.morning.rwmqp.cn.gov.cn.rwmqp.cn http://www.morning.wpcfm.cn.gov.cn.wpcfm.cn http://www.morning.xdhcr.cn.gov.cn.xdhcr.cn http://www.morning.zpyxl.cn.gov.cn.zpyxl.cn http://www.morning.ldgqh.cn.gov.cn.ldgqh.cn http://www.morning.glnfn.cn.gov.cn.glnfn.cn http://www.morning.pdgqf.cn.gov.cn.pdgqf.cn http://www.morning.dfojgo.cn.gov.cn.dfojgo.cn http://www.morning.rxydr.cn.gov.cn.rxydr.cn http://www.morning.qbrs.cn.gov.cn.qbrs.cn http://www.morning.qpsdq.cn.gov.cn.qpsdq.cn http://www.morning.niukaji.com.gov.cn.niukaji.com http://www.morning.touziyou.cn.gov.cn.touziyou.cn http://www.morning.kyjyt.cn.gov.cn.kyjyt.cn http://www.morning.bgdk.cn.gov.cn.bgdk.cn http://www.morning.xlwpz.cn.gov.cn.xlwpz.cn