跳转到内容

C Sharp Action 委托

来自代码酷

C# Action 委托[编辑 | 编辑源代码]

介绍[编辑 | 编辑源代码]

Action委托是C#中预定义的泛型委托类型,用于封装没有返回值的方法。它是.NET Framework中System命名空间的一部分,提供了一种简洁的方式来传递方法作为参数或存储方法引用。Action委托特别适用于事件处理、LINQ查询和异步编程等场景。

Action委托的特点:

  • 无返回值(返回类型为void
  • 可以接受0到16个输入参数
  • 通过泛型参数指定参数类型

基本语法[编辑 | 编辑源代码]

Action委托的声明形式如下:

// 无参数
Action actionName = MethodName;

// 带参数
Action<T1, T2, ..., T16> actionName = MethodName;

使用示例[编辑 | 编辑源代码]

无参数Action[编辑 | 编辑源代码]

using System;

class Program
{
    static void Greet()
    {
        Console.WriteLine("Hello, World!");
    }

    static void Main()
    {
        Action greetAction = Greet;
        greetAction(); // 调用委托
    }
}

输出:

Hello, World!

带参数Action[编辑 | 编辑源代码]

using System;

class Program
{
    static void PrintSum(int a, int b)
    {
        Console.WriteLine($"Sum: {a + b}");
    }

    static void Main()
    {
        Action<int, int> sumAction = PrintSum;
        sumAction(5, 3); // 传递参数并调用
    }
}

输出:

Sum: 8

匿名方法与Lambda表达式[编辑 | 编辑源代码]

Action委托常与匿名方法或Lambda表达式结合使用:

using System;

class Program
{
    static void Main()
    {
        // 使用匿名方法
        Action<string> printAction = delegate(string message)
        {
            Console.WriteLine(message);
        };

        // 使用Lambda表达式
        Action<string> lambdaAction = msg => Console.WriteLine(msg);

        printAction("Anonymous method");
        lambdaAction("Lambda expression");
    }
}

输出:

Anonymous method
Lambda expression

实际应用场景[编辑 | 编辑源代码]

1. 事件处理[编辑 | 编辑源代码]

Action委托常用于简化事件处理:

using System;

class Button
{
    public Action OnClick { get; set; }

    public void Click()
    {
        OnClick?.Invoke();
    }
}

class Program
{
    static void Main()
    {
        Button button = new Button();
        button.OnClick = () => Console.WriteLine("Button clicked!");
        button.Click();
    }
}

2. 集合操作[编辑 | 编辑源代码]

在LINQ或集合处理中使用Action:

using System;
using System.Collections.Generic;

class Program
{
    static void Main()
    {
        List<int> numbers = new List<int> { 1, 2, 3, 4, 5 };
        
        // 使用Action处理每个元素
        Action<int> printSquare = x => Console.WriteLine(x * x);
        numbers.ForEach(printSquare);
    }
}

输出:

1
4
9
16
25

3. 线程池任务[编辑 | 编辑源代码]

使用Action简化线程池任务提交:

using System;
using System.Threading;

class Program
{
    static void Main()
    {
        Action backgroundTask = () => 
        {
            Console.WriteLine("Background task started");
            Thread.Sleep(2000);
            Console.WriteLine("Background task completed");
        };

        // 在线程池中执行Action
        backgroundTask.BeginInvoke(null, null);
        
        Console.WriteLine("Main thread continues...");
        Thread.Sleep(3000); // 等待后台任务完成
    }
}

Action与Func的区别[编辑 | 编辑源代码]

classDiagram class Action{ +无返回值(void) +0-16个参数 } class Func{ +有返回值 +0-16个输入参数 +1个输出参数 } Action --|> Delegate Func --|> Delegate

数学表示:

  • Action: f:T1×T2×...×Tn
  • Func: f:T1×T2×...×TnTresult

高级用法[编辑 | 编辑源代码]

多播委托[编辑 | 编辑源代码]

Action支持多播委托(多个方法组合):

using System;

class Program
{
    static void Method1() => Console.WriteLine("Method 1");
    static void Method2() => Console.WriteLine("Method 2");

    static void Main()
    {
        Action multiAction = Method1;
        multiAction += Method2;
        
        multiAction(); // 依次调用两个方法
    }
}

输出:

Method 1
Method 2

泛型Action[编辑 | 编辑源代码]

使用泛型Action处理不同类型:

using System;

class Processor<T>
{
    public Action<T> ProcessAction { get; set; }

    public void Execute(T item)
    {
        ProcessAction?.Invoke(item);
    }
}

class Program
{
    static void Main()
    {
        var stringProcessor = new Processor<string>();
        stringProcessor.ProcessAction = s => Console.WriteLine(s.ToUpper());
        stringProcessor.Execute("hello");

        var intProcessor = new Processor<int>();
        intProcessor.ProcessAction = i => Console.WriteLine(i * 10);
        intProcessor.Execute(5);
    }
}

输出:

HELLO
50

性能考虑[编辑 | 编辑源代码]

  • Action委托调用比直接方法调用稍慢(纳秒级差异)
  • 对于性能关键代码,应考虑直接方法调用
  • 多播委托会按添加顺序依次调用所有方法,可能影响性能

总结[编辑 | 编辑源代码]

Action委托是C#中强大的功能,它:

  • 提供类型安全的方法引用
  • 简化代码结构
  • 支持函数式编程风格
  • 广泛应用于事件处理、LINQ和异步编程

掌握Action委托将显著提升你的C#编程能力,特别是在需要灵活方法传递的场景中。