在使用C++的时候,我们会经常用到指针函数和指针函数,最容易想到的用处就是用来处理回调函数,一个简易的情形就是当我们需要处理完一件事情之后,通过回调来处理当前的事情结束后处理另外的事情,比如读取完文本之后,从文本中解析对应的数据。C#也支持回调的处理方式,也就是委托。
委托是一种对象,包含了指向方法的引用,方法可以是静态方法,也可以是实例方法。通过它,可以定义类型安全的回调。最常用的委托的地方是事件处理。C#提供了几种常见的委托形式,可以根据实际情况去使用它们。
namespace System
{
using System.Runtime.CompilerServices;
public delegate void Action<in T>(T obj);
// Action/Func delegates first shipped with .NET Framework 3.5 in System.Core.dll as part of LINQ
// These were type forwarded to mscorlib.dll in .NET Framework 4.0 and in Silverlight 5.0
public delegate void Action();
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>(T1 arg1, T2 arg2, T3 arg3, T4 arg4);
public delegate TResult Func<out TResult>();
public delegate TResult Func<in T, out TResult>(T arg);
public delegate TResult Func<in T1, in T2, out TResult>(T1 arg1, T2 arg2);
public delegate TResult Func<in T1, in T2, in T3, out TResult>(T1 arg1, T2 arg2, T3 arg3);
public delegate TResult Func<in T1, in T2, in T3, in T4, out TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4);
public delegate void Action<in T1,in T2,in T3,in T4,in T5>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5);
public delegate void Action<in T1,in T2,in T3,in T4,in T5,in T6>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6);
public delegate void Action<in T1,in T2,in T3,in T4,in T5,in T6,in T7>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7);
public delegate void Action<in T1,in T2,in T3,in T4,in T5,in T6,in T7,in T8>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8);
public delegate TResult Func<in T1, in T2, in T3, in T4, in T5, out TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5);
public delegate TResult Func<in T1, in T2, in T3, in T4, in T5, in T6, out TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6);
public delegate TResult Func<in T1, in T2, in T3, in T4, in T5, in T6, in T7, out TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7);
public delegate TResult Func<in T1, in T2, in T3, in T4, in T5, in T6, in T7, in T8, out TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, T6 arg6, T7 arg7, T8 arg8);
public delegate int Comparison<in T>(T x, T y);
public delegate TOutput Converter<in TInput, out TOutput>(TInput input);
public delegate bool Predicate<in T>(T obj);
}
历史原因所致,委托都是多播委托,也就是会把添加到委托的所有目标函数视为一个整体执行。需要注意两个问题:
程序在执行这些目标函数的过程中可能发生异常;
程序会把最后执行的那个目标函数所返回的结果当成整个委托的结果。
所以在使用的时候,也需要注意这样的问题。