• C#中的委托是什么-下(Func与Action)


    参考资料:
    《C# 7.0本质论》13.2

    Func委托
    Action委托
    委托的内部机制

    自从C#3.0后,有了Func委托与Action委托,我们几乎不用再自己声明委托了。

    Func委托

    System.Func系列委托代表有返回值的方法。

    Func委托的声明,in符号后是接受的参数类型,out符号后是返回的值类型:

    public delegate TResult Func<out TResult>();
    public delegate TResult Func<in T1, out TResult>(T1 arg1);
    public delegate TResult Func<in T1, in T2, out TResult>(T1 arg1, T2 arg2);
    ...
    public delegate TResult Func<in T1,in T2,in T3,in T4,in T5,in T6,in T7,in T8,in T9,in T10,in T11,in T12,in T13,in T14,in T15,in T16,out TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16);
    

    假设有一个方法BubbleSort,它当然是用来排序的方法,但排序的规则不固定,可能要从大到小,可能要从小到大。比起在方法内部用if或者switch等语句来实现,用Func委托是一个更好的选择。

    // BubbleSort接受一个int型数组,接受一个Func委托,该委托接受两个int型参数,返回值类型为bool
    public static void BubbleSort(int[] items, Func<int, int, bool> compare)
    {
        // ...
    
    }
    
    public static bool GreaterThan(int first, int second)
    {
        return first > second;
    }
    
    static void Main(string[] args)
    {
        int[] items = { 1, 3, 2, 4, 5 };
    
        // 把GreaterThan方法作为BubbleSort方法的第二个参数传入
        BubbleSort(items, GreaterThan);
        // ...
    }
    

    如果想把比较的规则改为first < second,只需要实现方法LessThan,然后传给BubbleSort即可。使用lambda表达式是一种简单的方法。例如:

    BubbleSort(items, (first,second) => first > second);
    

    Action委托

    System.Action系列代表返回void的方法。

    Action委托的声明,in符号后是接受的参数类型:

    public delegate void Action();
    public delegate void Action<in T>(T obj);
    public delegate void Action<in T1,in T2>(T1 arg1, T2 arg2);
    public delegate void Action<in T1,in T2,in T3>(T1 arg1, T2 arg2, T3 arg3);
    ...
    public delegate void Action<in T1,in T2,in T3,in T4,in T5,in T6,in T7,in T8,in T9,in T10,in T11,in T12,in T13,in T14,in T15,in T16>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8, T9 arg9, T10 arg10, T11 arg11, T12 arg12, T13 arg13, T14 arg14, T15 arg15, T16 arg16);
    

    这里就不举例了。

    委托的内部机制

    委托实际是特殊的类。虽然C#标准没有明确说明类的层次结构,但委托必须直接或间接派生自System.Delegate。事实上,.NET委托总是派生自System.MulticastDelegate,后者又从System.Delegate派生,图为委托类型的对象模型:

    所有委托都不可变(immutable)。委托创建好后无法更改。如变量包含委托引用,并想引用不同的方法,只能创建新委托再把它赋给变量。委托执行+=与-=操作时实际也是新建了一个委托。

    虽然所有委托数据类型都间接从System.Delegate派生,但C#编译器不允许声明直接/间接从System.Delegate或者System.MulticastDelegate派生的类。

  • 相关阅读:
    【CodeForces 438D 】The Child and Sequence
    【雅礼集训 2017 Day1】市场
    【POJ2528】Mayor's posters
    【NOIP模拟】图论题Graph
    【BZOJ2654】Tree
    【NOIP模拟】函数
    【NOIP模拟】箱子
    【CQOI2014】数三角形
    【USACO2009Feb】股票市场
    【APIO2009-3】抢掠计划
  • 原文地址:https://www.cnblogs.com/Kit-L/p/13861829.html
Copyright © 2020-2023  润新知