前言:
一直对C#中的委托与事件不太了解,今天来正式学习一下,我跟着的课程,是这个网站的讲解
Action委托
我们新建一个C#项目
代码:
namespace Project_Action
{
class Program
{
static void Main(string[] args)
{
//第一种应用 将方法当成参数来进行传递
Test(Test2);
Console.ReadLine();
}
//执行完之后,我还有一些事情要继续执行,但是我暂时不知道
//是要调用哪个接口
public static void Test(Action action) {
Console.WriteLine("执行完Test方法了");
if (action != null) {
action();
}
}
public static void Test2() {
Console.WriteLine("执行完Test2方法了");
}
}
}
如示例,第一种使用方法就是这样将另一个方法作为参数调用。
另外
我们还可以这样利用Action委托
namespace Project_Action
{
class Program
{
static Action mAction;
static void Main(string[] args)
{
//与委托绑定了的方法,在委托调度的时候,就会被执行
mAction += Test1;
mAction += Test2;
mAction();
//不需要条用的时候,从绑定的列表汇总移除
mAction -= Test2;
mAction();
Console.ReadLine();
}
//执行完之后,我还有一些事情要继续执行,但是我暂时不知道
//是要调用哪个接口
public static void Test1() {
Console.WriteLine("执行完Test1方法了");
}
public static void Test2() {
Console.WriteLine("执行完Test2方法了");
}
}
}
+=:用于多个方法绑定给委托
= :用于单个方法绑定给委托
如果我们想要给Action委托添加参数呢?
namespace Project_Action
{
class Program
{
static Action<int,string> mAction;
static void Main(string[] args)
{
//与委托绑定了的方法,在委托调度的时候,就会被执行
mAction += Test1;
int a = 3;
string b = "Hello";
mAction(a,b);
Console.ReadLine();
}
//执行完之后,我还有一些事情要继续执行,但是我暂时不知道
//是要调用哪个接口
public static void Test1(int a,string b) {
Console.WriteLine("第"+a+"个:"+b);
}
}
}
以上就是Action委托的基本用法。
Action委托有一个大缺点:不支持返回值,所以后面才有了Func委托
Func委托
使用Func来实现带有返回值的委托调用
可以绑定带有返回值的方法,并且接受其返回值
namespace Project_Action
{
class Program
{
static Func<int, int, int> func1;
static void Main(string[] args)
{
//将方法与委托进行绑定
func1 = Test;
int result=func1(50,16);
Console.WriteLine(result);
//不管是+=还是=,都要取消委托的注册,移除委托绑定的方法
func1 -= Test;
Console.ReadLine();
}
public static int Test(int a,int b) {
return (a + b);
}
}
}
打印:66
另外func也可以像Action一样作为参数传递
namespace Project_Action
{
class Program
{
static Func<int, int, int> func1;
static void Main(string[] args)
{
int result=Test(Test2, 100,500);
Console.WriteLine(result);
Console.ReadLine();
}
public static int Test(Func<int,int,int> callback,int a,int b) {
if (callback!=null) {
return callback(a,b);
}
return 0;
}
public static int Test2(int a,int b) {
return a * b;
}
}
}
输出:50000
Delegate委托
这种委托比上面那两古老一些,而且语法也相对复杂一点,这个委托可以带返回值,也可以不带。
简单使用方法
namespace Project_Action
{
class Program
{
//定义委托原型(此例无返回值无参数)
delegate void MyDelegate();
//通过定义的delegate创建一个事件
static MyDelegate delegate1;
static void Main(string[] args)
{
Console.WriteLine("第一次调用");
delegate1 += Test1;
delegate1 += Test2;
delegate1();
Console.WriteLine("第二次调用");
delegate1 -= Test1;
delegate1();
Console.ReadLine();
}
static void Test1() {
Console.WriteLine("test1被执行");
}
static void Test2()
{
Console.WriteLine("test2被执行");
}
}
}
另外它也有作为参数的方法:
namespace Project_Action
{
class Program
{
//定义委托原型(此例无返回值无参数)
delegate void MyDelegate();
//通过定义的delegate创建一个事件
static MyDelegate delegate1;
static void Main(string[] args)
{
Test(Test1);
Console.ReadLine();
}
static void Test(MyDelegate d) {
Console.WriteLine("test被执行");
if (d != null) {
d();
}
}
static void Test1()
{
Console.WriteLine("test1被执行");
}
}
}
如果需要参数
namespace Project_Action
{
class Program
{
//定义委托原型(此例无返回值无参数)
delegate void MyDelegate();
//通过定义的delegate创建一个事件
static MyDelegate delegate1;
delegate void MyDelegate2(int a,int b);
static MyDelegate2 delegate2;
static void Main(string[] args)
{
Test(Test1,100,200);
Console.ReadLine();
}
static void Test(MyDelegate2 d,int a,int b) {
Console.WriteLine("test被执行");
if (d != null) {
d(a,b);
}
}
static void Test1(int a,int b)
{
Console.WriteLine("test1被执行"+a+b);
}
}
}
返回值也是一样的道理,就不做示范了。
Event事件
event实际上是对Delegate的一个封装
我们来举个例子:
一个命令空间下有两个类——Player和Program
class Player
{
public delegate void myDelegate();
public event myDelegate d1; //事件
}
class Program
{
static void Main(string[] args)
{
Player player = new Player();
player.d1 += Test1;
player.d1();
Console.ReadLine();
}
static void Test1() {
Console.WriteLine("我是Test1");
}
}
然后我们会发现报错
这就是Event的作用,它限制了Delegate委托绑定的方法必须在Player中调用。
class Player
{
public delegate void myDelegate();
public event myDelegate d1; //事件
public void Call() {
if (d1 != null) {
d1();
}
}
}
class Program
{
static void Main(string[] args)
{
Player player = new Player();
player.d1 += Test1;
player.Call();
Console.ReadLine();
}
static void Test1() {
Console.WriteLine("我是Test1");
}
}
输出:我是Test1
从上面的实验,我们得出:
事件,实际就是对委托的一个限制,让委托的调度只能限制在这个类的内部(在别的类中可以进行注册/移除的操作,但是不能调用)
总结:
C#中的委托大致就是这些内容了,它主要的作用其实就是去解耦各个模块;避免直接调度其他模块的方法、而是通过注册/移除来控制其他模块方法的调度。
委托是一个非常好的策略,比如在游戏制作中,战斗开始之后,无需调用英雄的初始化、音乐的初始化、场景的初始化,可以直接在一个委托中直接调用。
商业转载 请联系作者获得授权,非商业转载 请标明出处,谢谢