显示页面讨论反向链接回到顶部 本页面只读。您可以查看源文件,但不能更改它。如果您觉得这是系统错误,请联系管理员。 ====== C# 委托 (Delegate) 深度解析 ====== 委托是 C# 中一种非常重要的引用类型,它是函数式编程在 C# 中的基础。 ===== 1. 简介 ===== **关键字**:%%delegate%% (读音: /'dɛlɪɡət/) **核心概念**: * 委托将**方法(函数)当作变量**进行处理。 * 委托是一种**引用类型**,它定义了方法的签名(Signature)。 * 只要方法的签名(返回值类型 + 参数列表)与委托定义一致,该方法就可以赋值给委托变量。 **通俗理解**:委托就像是一个“办事处代表”。你定义了这个代表能办什么事(比如能接收两个整数,返回一个整数)。任何符合这个标准的具体办事员(具体方法),都可以被指派给这个代表去执行任务。 ===== 2. 委托的使用步骤 ===== 使用自定义委托通常分为三步: - **定义 (Define)**:像定义类一样,在类外部(或内部)声明委托类型。 - **实例化 (Instantiate)**:创建委托对象,并指向一个具体的方法。 - **调用 (Invoke)**:像调用函数一样调用委托对象。 <code csharp> // 1. 声明委托 (规定了必须是:两个int参数,返回bool) public delegate bool CompareDelegate(int a, int b); class Program { static void Main() { // 2. 实例化委托,指向 IsGreater 方法 // 注意:这里只写方法名,不要带括号() CompareDelegate compare = IsGreater; // 3. 调用委托 bool result = compare(5, 3); Console.WriteLine($"Is 5 greater than 3? {result}"); } // 具体方法:签名必须与委托一致 static bool IsGreater(int a, int b) { return a > b; } } </code> ===== 3. 委托应用场景举例 ===== ==== 案例 1:逻辑解耦 (字符串过滤器) ==== 委托允许我们将判断逻辑从主流程中剥离出来。 <code csharp> using System; // 定义委托:接收 string,返回 bool public delegate bool StringFilter(string input); class Program { static void Main() { // 这里的逻辑是可以动态替换的 StringFilter filter = IsLongEnough; bool result = filter("Hello, World!"); Console.WriteLine($"Is 'Hello, World!' long enough? {result}"); } static bool IsLongEnough(string input) { return input.Length >= 10; } } </code> ==== 案例 2:跨类调用 ==== 如果委托需要指向另一个类的方法,需要先实例化那个类。 <code csharp> class Program { // 自定义委托类型 public delegate int MathOpDelegate(int a, int b); static void Main(string[] args) { // 1. 实例化包含方法的类 Calculator calc = new Calculator(); // 2. 委托指向该实例的成员方法 MathOpDelegate myDelegate = calc.Multiply; // 注意:不要加括号() // 3. 执行委托 int result = myDelegate(5, 7); Console.WriteLine($"结果: {result}"); // 输出 35 } } class Calculator { public int Multiply(int a, int b) { return a * b; } } </code> ===== 4. 系统预定义委托 (Action & Func) ===== 为了避免每次使用委托都要先写 `public delegate ...`,C# 提供了两个通用的泛型委托。 ^ 委托类型 ^ 返回值 ^ 用途 ^ 格式示例 ^ | **Action** | **无 (void)** | 执行动作,不需结果 | %%Action<T1, T2>%% | | **Func** | **有 (TResult)** | 计算并返回结果 | %%Func<T1, T2, TResult>%% | ==== Action 委托 (无返回值) ==== `Action` 后面尖括号里的类型全是**输入参数**。 <code csharp> static void Main() { // Action<string> 表示:接收一个 string 参数,无返回值 Action<string> print = PrintMessage; print("Hello, System Delegate!"); } static void PrintMessage(string message) { Console.WriteLine(message); } </code> ==== Func 委托 (有返回值) ==== `Func` 后面尖括号里,**最后一个类型永远是返回值类型**,前面的都是输入参数类型。 <code csharp> static void Main() { // Func<int, int, int> 表示: // 输入参数1: int // 输入参数2: int // 返回值: int Func<int, int, int> addFunc = Add; int sum = addFunc(3, 4); Console.WriteLine($"3 + 4 = {sum}"); } static int Add(int a, int b) { return a + b; } </code> ===== 5. 匿名方法与 Lambda 表达式 ===== 有时我们只需要一个简单的逻辑,专门写一个静态函数太麻烦,这时可以使用匿名方法。 ==== 匿名方法 (C# 2.0 写法) ==== 在实例化委托时,直接使用 `delegate` 关键字定义方法体。 <code csharp> public delegate int MathDelegate(int a, int b); static void Main(string[] args) { // 直接内联定义逻辑,没有方法名 MathDelegate multiply = delegate (int a, int b) { return a * b; }; int result = multiply(5, 7); Console.WriteLine(result); } </code> ==== 知识拓展:Lambda 表达式 (C# 3.0+ 推荐写法) ==== 现代 C# 开发中,几乎不再使用 `delegate (...) {}` 的匿名方法写法,而是使用更简洁的 **Lambda 表达式** (`=>`)。 <code csharp> static void Main(string[] args) { // 这里的 (a, b) => a * b 等同于上面的匿名方法 // => 读作 "goes to" Func<int, int, int> multiply = (a, b) => a * b; int result = multiply(5, 7); Console.WriteLine(result); } </code> ===== 总结 ===== - **定义**:委托是方法的容器,可以把方法当参数传递。 - **自定义**:使用 `delegate` 关键字定义签名。 - **系统内置**: - `Action`: 无返回值。 - `Func`: 有返回值(最后一个泛型参数是返回类型)。 - **进化**:从 `自定义委托` -> `Action/Func` -> `匿名方法` -> `Lambda表达式`,代码越来越简洁。 登录 Detach Close 该主题尚不存在 您访问的页面并不存在。如果允许,您可以使用创建该页面按钮来创建它。 csharp/类/委托.txt 最后更改: 2025/11/27 10:15由 张叶安 登录