Func
是 C# 中一种泛型委托(Delegate),用于封装具有返回值的方法。它是 .NET Framework 中预定义的委托类型,支持最多 16 个输入参数,并始终返回最后一个泛型参数指定的类型。以下是其核心知识点与应用场景:
1. Func
的定义与基础用法
Func
的声明形式为:
Func<T1, T2, ..., TResult>
- 输入参数:
T1, T2, ...
表示方法的输入参数类型(最多 16 个)。 - 返回值:
TResult
表示方法的返回值类型。
示例:
// 定义一个接受两个整数参数并返回字符串的 Func
Func<int, int, string> SumToString = (a, b) => (a + b).ToString();
string result = SumToString(3, 5); // 返回 "8"
应用场景:
- 动态调用方法:将方法作为参数传递,例如在算法中注入自定义逻辑。
- LINQ 查询:LINQ 的
Select
、Where
等方法依赖Func
实现数据转换和过滤。
2. Func
与 Action
的区别
- **
Func
:封装有返回值**的方法。 - **
Action
:封装无返回值**的方法(即void
方法)。
示例对比:
// Func 示例
Func<int, bool> IsEven = num => num % 2 == 0;
bool check = IsEven(4); // true
// Action 示例
Action<string> LogMessage = msg => Debug.Log(msg);
LogMessage("Hello World"); // 输出到控制台
3. Func
的实际应用场景
**(1) 回调函数与事件处理**
在 Unity 中,Func
可用于定义回调机制。例如,实现一个异步加载系统:
public void LoadResource(string path, Func<bool> onComplete) {
StartCoroutine(LoadAsync(path, onComplete));
}
private IEnumerator LoadAsync(string path, Func<bool> callback) {
// 模拟异步加载
yield return new WaitForSeconds(2);
bool success = true;
callback?.Invoke(success); // 调用回调函数
}
调用时:
LoadResource("Assets/Enemy.prefab", (isSuccess) => {
if (isSuccess) Debug.Log("加载成功");
return true;
});
**(2) 动态逻辑注入**
在策略模式中,通过 Func
实现灵活的行为切换。例如,敌人 AI 的不同状态逻辑:
public class EnemyAI : MonoBehaviour {
private Func<EnemyState> _currentBehavior;
public void SetBehavior(Func<EnemyState> behavior) {
_currentBehavior = behavior;
}
void Update() {
var state = _currentBehavior?.Invoke();
// 根据 state 执行动作
}
}
// 使用示例
enemyAI.SetBehavior(() => {
if (health < 30) return EnemyState.Flee;
return EnemyState.Attack;
});
**(3) 与 Lambda 表达式结合**
Func
常与 Lambda 表达式配合,简化代码:
// 筛选列表中的偶数
List<int> numbers = new List<int> { 1, 2, 3, 4 };
var evenNumbers = numbers.Where(n => n % 2 == 0).ToList();
此处 Where
方法的参数本质上是 Func<int, bool>
。
4. 在 Unity 编辑器扩展中的应用
虽然 Func
本身不直接涉及编辑器功能,但结合 Unity 的 API 可实现高级扩展。例如:
- 自定义属性检查器:通过
Func
动态生成 Inspector 中的交互逻辑。 - 自动化测试工具:用
Func
封装测试用例的执行条件。
示例:动态生成按钮并绑定方法(类似网页1中提到的 OnInspectorGUI
的按钮逻辑):
[CustomEditor(typeof(MyComponent))]
public class MyComponentEditor : Editor {
public override void OnInspectorGUI() {
base.OnInspectorGUI();
if (GUILayout.Button("执行操作")) {
Func<bool> action = () => {
// 执行复杂逻辑
return true;
};
bool result = action.Invoke();
Debug.Log(result ? "成功" : "失败");
}
}
}
5. 注意事项与最佳实践
- 性能优化:频繁创建
Func
实例可能导致内存压力,建议复用委托或使用静态方法。 - 可读性:避免过度使用复杂 Lambda 表达式,必要时封装为具名方法。
- 多线程安全:在 Unity 主线程外调用
Func
时需注意线程同(如MainThreadDispatcher
)。
总结
Func
是 C# 中实现方法抽象与灵活调用的核心工具,适用于回调、动态逻辑、LINQ 查询等场景。在 Unity 开发中,结合事件系统和编辑器扩展,能显著提升代码的模块化与可维护性。