C# 关于事件默认处理方法名称

Haitani 2020-07-13 09:01:35
求教:自定义一个类Tester,其中定义了一个事件:StateChanged,在Form1中new一个Tester,并且+=注册StateChanged事件,提示的默认事件处理方法名为:Form1_StateChanged,也就是说Tab两下后出来的方法为Form1_StateChanged,如何让默认的方法名为Tester_StateChanged,而不是必须每次手动改,谢谢各位
...全文
805 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
八爻老骥 2020-07-13
  • 打赏
  • 举报
回复
+=的时候改下不就是了,又费不了少事。不过VS自动生成的代码确实丑,如果窗体里有几十个事件,那代码简直让人反胃,还好有Lamda和Command模式。
datafansbj 2020-07-13
  • 打赏
  • 举报
回复
没有必要,Forn1 并不知道你要注册的函数名称从何而来,最合理的当然是自己类里定义的函数(即默认函数前缀为 Form1,这样不会引起误解)。
  • 打赏
  • 举报
回复
复合委托列表


我经常拿微信举例子,微信假设有20万台服务器,几十亿用户每一个用户都连在某台服务器上,当用户A给用户B发送消息的时候,消息最终推送给B用户终端,可见只有服务器到B终端的一跳事件。而一些培训班上的“项目”竟然教人说微信是B每隔1秒钟去轮询服务器去取消息,这只能是当作一个练习,可见如果几万个用户都是1秒轮询一次“一台”服务器,那么别说服务器,这时候网络早就瘫痪了。更何况20万台服务器呢?

事件是最基本的设计。能把初学的时候的那种消息控制的思路“倒过来”,就好像你吃东西从被填鸭变为自己选择营养,是个巨大进步。
  • 打赏
  • 举报
回复
事件的“优势”这个简单说出来也真的是众口难调。而当你做项目、做架构时其实又是那么“自然而然”。当你设计一个对象,你想设计扩展接口,自然用委托属性,进而用更标准的事件语法。如果写
public xxx StateChanged;
(这里的xxx是一种委托)定义,那么任何宿主就可以写代码
Tester.StateChanged = aaa;
来篡改委托了。而 Event 关键字告诉编译器,不允许随便修改这种委托,只能用 +=、-= 等少量语法,保护了安全性。

委托对象实际上在编译之后会变为一种“符合委托列表”,也就是说尽管定义 StateChanged是一个委托,真正 c# 产生的代码其实是一个“委托管理”对象,可以给它插入多个实例对象。这也是方便了 Event 的实现。

从设计模式上说,事件是通知的标准形式。然而如果你看《设计模式》这本书的作者四人帮(GOF)在上个世纪90年代并不懂事件机制(虽然那个时候微软的 vb 1.0 for dos 早已经用事件机制来架构界面开发模式了),因此它写了20几种模式。实际上如果使用事件,那么那本书起码可以缩小80%篇幅。事件是作为服务的一方主动回调——通知——客户宿主,它跟宿主代码轮询、不顾死活去冲击人家服务是相反的。一旦有准确及时的通知机制,后者就会被精简到原来的百分之一、千分之一,隔很长时间才轮询一下了。

软件工程的设计不要“为了编代码而编代码"。c# 代码固然可以佐证软件工程概念,但是软件工程概念高于编程语言。当 c# 语法离良好的软件工程需求过于离谱的时候,我们可能就抛弃 c# 语言而去选择更好的语言了。因此先要了解“事件”的机制,去看看各种编程语言是如何定义和使用事件的,不要只纠结一种语言。脱离开某种编程语言而根据工程设计来写代码,才能更好地使用编程语言。
threenewbee 2020-07-13
  • 打赏
  • 举报
回复
你可以反过来,先写
Tester.StateChanged += Tester_StateChanged;
然后因为Tester_StateChanged没有,所以代码补全,生成一个Tester_StateChanged的空方法
Haitani 2020-07-13
  • 打赏
  • 举报
回复
引用 8 楼 以专业开发人员为伍 的回复:
如果你在 new 一个 Tester 之后,宿主程序需要为它分别挂接2个甚至3个处理过程,你用“按Tab两下”也还是没法生成。你得写 += ...... 这样的代码。所以别纠结 vs 的工具的问题。用 c# 语法去创造点代码风格,就好了。
sp1234前辈你好,经常看到你说事件驱动,然后也看到消息驱动,想请教一下,1:事件驱动的其一优势是避免轮询检查(比如对值变化)的频繁操作?2:事件驱动和消息驱动的区别是啥?谢谢
github_36000833 2020-07-13
  • 打赏
  • 举报
回复
做起来很麻烦的。 首先,你要理解如何扩展VisualStudio,可以先阅读: 【开始开发 Visual Studio 扩展】 https://docs.microsoft.com/zh-cn/visualstudio/extensibility/starting-to-develop-visual-studio-extensions?view=vs-2019 然后,要理解Designer宿主设计架构,比如可以先阅读(标记为dotnet2.0,但概念相同): 【Create And Host Custom Designers With The .NET Framework 2.0】 https://docs.microsoft.com/en-us/archive/msdn-magazine/2006/march/create-and-host-custom-designers-with-the-net-framework-2-0 然后,你就可以通过实现IEventBindingService接口,并自定义其中的CreateUniqueMethodName,来按照你自己的规则生成你想要的事件响应函数名。 最后,安装你开发的Visual Studio扩展,从此享用“不是必须每次手动改”的快乐;-)
  • 打赏
  • 举报
回复
如果你在 new 一个 Tester 之后,宿主程序需要为它分别挂接2个甚至3个处理过程,你用“按Tab两下”也还是没法生成。你得写 += ...... 这样的代码。所以别纠结 vs 的工具的问题。用 c# 语法去创造点代码风格,就好了。
  • 打赏
  • 举报
回复
是的,处理过程是属于 Form1 的而不是 Tester 的。这里起名字能说明 lz 对于事件的概念还是有误区。

在 Tester 所属类型上定义事件,那么事件的接口定义都在 Tester,触发也在 Tester。这样 Tester 就是一个服务,而 Form1 是个宿主(客户)。是 Form1 定义了处理过程,而 Tester 只是定义了接口规范。
wanghui0380 2020-07-13
  • 打赏
  • 举报
回复
改是可以改的,比如我们用Resharp自己定义模板 但是其实不建议。假设我有两个控件,然后呢。 你觉着我应该写成 object1_load object2_load 还是应该写成 form1_load1 form1_load2
  • 打赏
  • 举报
回复
实际上,我觉得 .net 中的可修改配置、甚至直接用注入的动态太多太滥,引起各种底层技术争论,已经对小白跟其它技术体系竞争造成了不好的影响。过去的 vs 下的框架总是提供相对简单直观的一套千锤百炼测试好、中上等的默认参数,而且基本上不让修改(要修改就得去手动修改注册表),挺好的。

实际上你可以选择更简洁的编程理念,例如匿名、显式委托。例如
control.evt += (s,arg)=>
{
.....
};
或者
var myProc = new EventHandlerXX( (s,arg)=>
{
.....
});
ctr1.evt += myProc;
ctr2.evt += myProc;
......
ctr1.evt -= myProc;
ctr2.evt -= myProc;


你想给处理过程起名字,就先“独立”拥有这个过程对象。
  • 打赏
  • 举报
回复
这个可能需要买下微软。毕竟“不必须每次手动改”的需求能每一个程序员都能提出几十个,众口难调。
Haitani 2020-07-13
  • 打赏
  • 举报
回复

110,534

社区成员

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

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

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