Unity学习笔记(二):委托,匿名函数,闭包

Unity学习笔记(二):委托,匿名函数,闭包
最新回答
紫珺婳浅

2023-04-29 03:04:17

Unity学习笔记(二):委托,匿名函数,闭包委托

定义与理解

委托,从字面上理解是帮忙做一系列事情的东西,在代码中也就是帮忙调用一系列方法的东西。但委托并非简单地按顺序执行一系列方法,其核心在于其灵活性和动态性。你可以实时地添加或删除想要调用的方法,也可以将其当作参数传到函数中去(回调)。委托可以看作是一个存储了函数的数组,单播委托可以理解为函数指针,多播委托则是一系列函数指针的集合。

声明与使用

  • 单播委托:public delegate void MyDelegate(int x); 这是一个简单的委托声明,表示一个接受整型参数、无返回值的委托类型。但需要注意的是,这只是一个委托类型,要实际使用还需要实例化。
  • 多播委托:多播委托可以添加多个方法,通过+=添加方法,通过-=移除方法。
  • 简化声明:在Unity开发中,一般不会直接使用delegate关键字声明委托,而是使用Action或Func。Action无返回值,Func有返回值。例如:public Action<int> OnMoneyChanged; 或 public Func<int, bool> OnMoneyChangedFunc;。

应用场景

委托通常用于逻辑模块与UI模块的交互中。逻辑类中会定义一系列委托,当某个数据发生更改时调用对应的委托,UI类中会定义一个更新UI的函数,并添加到这个委托上。这样逻辑类就不用管任何关于UI的事情了。更广义点讲,委托用于信息传递,当某某事件发生时,某些模块应该要做什么。

事件与委托的区别

事件是在委托的前面加一个event修饰词,是特殊的委托,为委托的使用加上了许多限制条件。事件只能在方法外部声明,并且在其他类中只能添加或删除方法,不能调用。这增加了代码的安全性和封装性。

匿名函数

定义与特点

匿名函数就是没有名称的函数,没法通过函数名调用它,因此只能当场添加到委托中来调用它。匿名函数的好处是用起来方便,特别是在数据处理中,比如按照某种规则进行排序时,非常直观。

语法与用法

匿名函数的语法通常使用Lambda表达式,例如:(a, b) => (a + b) 表示一个接受两个参数并返回它们之和的匿名函数。在Unity中,匿名函数常用于LINQ查询、事件监听等场景。

应用场景

  • LINQ查询:使用匿名函数对集合进行排序、筛选等操作。
  • 事件监听:为UI控件添加事件监听器时,可以使用匿名函数来简化代码。
闭包

定义与问题

闭包是为了解决在委托或匿名函数中访问局部变量时,局部变量生命周期延长的问题。在C#中,当你将一个匿名函数(或Lambda表达式)添加到一个委托中时,如果这个匿名函数引用了局部变量,那么这些局部变量的生命周期会被延长,直到委托被垃圾回收。

内部实现

编译器会将匿名函数封装进一个临时的类中,并将引用的局部变量作为这个类的成员变量。这样,当匿名函数被调用时,它就可以通过这个临时类的实例来访问这些局部变量。

闭包陷阱

闭包陷阱通常发生在多次修改闭包中引用的局部变量时。由于闭包会捕获变量的引用而不是值,因此如果闭包外部修改了这些变量,闭包内部访问到的将是修改后的值。这可能会导致一些难以察觉的错误。

解决方法

为了避免闭包陷阱,可以在闭包外部声明一个新的局部变量,并将需要捕获的变量的值赋给这个新的局部变量。然后,在闭包内部使用这个新的局部变量。这样,闭包捕获的就是这个新的局部变量的值,而不是原始变量的引用。

应用场景

闭包在Unity开发中常用于UI事件处理、动画回调等场景。在这些场景中,经常需要访问一些局部变量或实例变量,而闭包提供了一种方便的方式来延长这些变量的生命周期并访问它们。

总结

委托、匿名函数和闭包是C#中非常重要的概念,它们在Unity开发中有着广泛的应用。理解这些概念的原理和动机,掌握它们的使用场景和注意事项,对于提高代码的可读性、可维护性和灵活性具有重要意义。