原文链接:(51条消息) C# Event Action与Invoke_c# action invoke_GTWLin的博客-CSDN博客
趁着1024这个好日子来讲一下
通常在C# 中
为了将功能模块化
我们会把重复使用的功能写到类 (Class)里面
但是写在类里面的方法是无法直接对主窗体界面进行操作的
这个时候我们就需要使用 “委托”
关于委托的讲解可以参考这篇
https://www.cnblogs.com/wudiwushen/archive/2010/04/20/1703368.html
讲的挺浅显易懂的
但随着时代的进步
程式语言也在进步(人越来越懒)
现在我们只需要在类中声明一个Event Action的变量
就可以让随时呼叫并执行我们在主界面的方法
而主界面的方法就可以对界面进行操作拉
1 | 类 |
1 | Form1 |
Form1中+=使用的就是一个委托的概念
意思是当c1 这个object(类的实例化)里面的Call (呼叫)这个Event Action的时候
会呼叫到Form1 (主界面)中的Called (被呼叫)方法


这个时候的顺序应该是
- 按下button1
- 执行c1.show()
- show方法中执行Call.Invoke()
- Call.Invoke()呼叫Called方法执行 (因为 c1.Call += Called这句)
- 执行Called方法
- 将Label1的文字修改为 “123”
那么若是
多了一个button里头执行
1 | private void button2_Click(object sender, EventArgs e) |
会发生什么事?

我们再理清一下顺序
按下button1
执行c1.show()
show方法中执行Call.Invoke()
Call.Invoke()呼叫Called方法执行 (因为 c1.Call += Called这句)
执行Called方法
将Label1的文字修改为 “123”
--------到这边位置都一样--------
按下button2 (c1.Call -= Called 取消注册)
按下button1
执行c1.show()
show方法中执行Call.Invoke()
因为Call并没有注册任何的方法,系统不知道要呼叫谁就报错了
那有没有方法避免呢? 是有的
1 | public void Show() |
看得出来差在哪里吗?
其实就只加了一个?上去而已
但这个问号在的功用等于
if (Call != null) { Call.invoke();}
因为Call并未注册 (被取消注册) 所以没有任何值或地址在里面
所以便不会执行Call.Invoke()了
再来 如果我们要将变量透过invoke()传递该怎么做呢?
很简单
1 | 类 |
1 | Form1 |
当然 你也可以不只传递一个参数
1 | public event Action<int, string, string> Call; |
1 | Class1 c1; |
