C# 的四种委托实现详解
当前位置:点晴教程→知识管理交流
→『 技术文档交流 』
一、什么是委托1.1 官方解释委托是一种定义方法签名的类型。当实例化委托时,您可以将其实例与任何具有兼容签名的方法相关联,并通过委托实例调用该方法。 1.2 个人理解委托就是用于封装和执行方法(函数)的一个类。 ★ 二、如何声明委托C# 中有四种常见的委托声明方式: 2.1 |
delegate | ||
Action | void) | |
Func | ||
Predicate | 仅 1 个 | bool |
★注:部分资料中提到 Action/Func 最多支持 4 个参数,这是早期 .NET 版本限制;现代 C#(.NET Framework 4.0+ / .NET Core)已支持最多 16 个参数。
delegate 的使用public delegate int MethodDelegate(int x, int y);
private static MethodDelegate method;
static void Main(string[] args)
{
method = new MethodDelegate(Add);
Console.WriteLine(method(10, 20)); // 输出:30
Console.ReadKey();
}
private static int Add(int x, int y) => x + y;
Action 的使用static void Main(string[] args)
{
Test<string>(Action, "Hello World!");
Test<int>(Action, 1000);
Test<string>(p => Console.WriteLine("{0}", p), "Lambda Hello");
Console.ReadKey();
}
public static void Test<T>(Action<T> action, T p) => action(p);
private static void Action(string s) => Console.WriteLine(s);
private static void Action(int s) => Console.WriteLine(s);
★
Action常用于执行操作,无需返回结果。
Func 的使用static void Main(string[] args)
{
Console.WriteLine(Test<int, int>(Fun, 100, 200)); // 输出:300
Console.ReadKey();
}
public static int Test<T1, T2>(Func<T1, T2, int> func, T1 a, T2 b) => func(a, b);
private static int Fun(int a, int b) => a + b;
★
Func常用于需要返回计算结果的场景。
Predicate 的使用static void Main(string[] args)
{
Point[] points = {
new Point(100, 200),
new Point(150, 250),
new Point(250, 375),
new Point(275, 395),
new Point(295, 450)
};
Point first = Array.Find(points, ProductGT10);
Console.WriteLine("Found: X = {0}, Y = {1}", first.X, first.Y);
Console.ReadKey();
}
private static bool ProductGT10(Point p) => p.X * p.Y > 100000;
★
Predicate常用于集合筛选(如Array.Find,List.FindAll等)。
public MethodDelegate OnDelegate;
public void ClearDelegate()
{
while (OnDelegate != null)
{
OnDelegate -= OnDelegate;
}
}
★⚠️ 注意:此写法在多线程环境下可能不安全,且逻辑上存在争议(每次减去自身可能导致未完全清除)。更推荐方法二。
GetInvocationListpublic MethodDelegate OnDelegate;
static void Main(string[] args)
{
Program test = new Program();
if (test.OnDelegate != null)
{
Delegate[] dels = test.OnDelegate.GetInvocationList();
foreach (var del in dels)
{
test.OnDelegate -= (MethodDelegate)del;
}
}
}
★此方法安全可靠,适用于多播委托的彻底清空。
delegateActionvoid)FuncPredicatebool
参考资料: