全面解析:C# 委托的实质性应用与优势
共 12773字,需浏览 26分钟
·
2024-06-20 17:01
前言
有人问C#的委托(Delegate)有什么实质性用途?委托在C#其实是无处不在,那么它具体用在那里呢?。
本文将从委托(Delegate)定义和演变讲起,让大家一目了然。
C#的委托(Delegate)是强类型的函数指针,用于引用方法并允许将方法作为参数传递。随着C#的演变,委托的功能和用途变得越来越强大和灵活。
本文将从C#委托的演变谈起,详细介绍其实质性用途,并通过代码实例加以证明。
委托的演变
C# 1.0: 基本委托
在C# 1.0中,引入了基本的委托概念,使得方法可以作为对象传递。这是实现事件和回调机制的基础。
using System;
public delegate void Notify(); // 声明委托
public class ProcessBusinessLogic
{
public event Notify ProcessCompleted; // 使用委托声明事件
public void StartProcess()
{
Console.WriteLine("Process Started!");
// 模拟一些处理任务
System.Threading.Thread.Sleep(3000);
// 处理完成后触发事件
OnProcessCompleted();
}
protected virtual void OnProcessCompleted()
{
ProcessCompleted?.Invoke();
}
}
class Program
{
static void Main(string[] args)
{
ProcessBusinessLogic bl = new ProcessBusinessLogic();
bl.ProcessCompleted += Bl_ProcessCompleted; // 订阅事件
bl.StartProcess();
}
private static void Bl_ProcessCompleted()
{
Console.WriteLine("Process Completed!");
}
}
C# 2.0: 匿名方法
C# 2.0引入了匿名方法,使得委托的使用更加灵活,不需要单独定义方法即可实现回调。
using System;
public delegate void Print(int value);
public class Program
{
public static void Main(string[] args)
{
Print print = delegate(int val) {
Console.WriteLine("Anonymous method: {0}", val);
};
print(100);
}
}
C# 3.0: Lambda表达式
C# 3.0进一步引入了Lambda表达式,简化了委托的语法,使得代码更加简洁和易读。
using System;
public delegate void Print(int value);
public class Program
{
public static void Main(string[] args)
{
Print print = (val) => Console.WriteLine("Lambda expression: {0}", val);
print(200);
}
}
C# 4.0及以后: 泛型委托和内置委托类型
随着C#的不断发展,泛型委托和内置委托类型(如Action
、Func
和Predicate
)被引入,进一步增强了委托的功能和灵活性。
using System;
public class Program
{
public static void Main(string[] args)
{
Action<int> print = val => Console.WriteLine("Action delegate: {0}", val);
print(300);
Func<int, int> square = x => x * x;
Console.WriteLine("Func delegate: {0}", square(5));
Predicate<int> isPositive = x => x > 0;
Console.WriteLine("Predicate delegate: {0}", isPositive(10));
}
}
委托的实质性用途
1、简单回调机制
在编写需要回调功能的代码时,委托可以扮演重要角色。例如,当一个方法完成某项任务时,可以通过回调通知调用者。
using System;
public delegate void Notify(); // 声明委托
public class ProcessBusinessLogic
{
public event Notify ProcessCompleted; // 使用委托声明事件
public void StartProcess()
{
Console.WriteLine("Process Started!");
// 模拟一些处理任务
System.Threading.Thread.Sleep(3000);
// 处理完成后触发事件
OnProcessCompleted();
}
protected virtual void OnProcessCompleted()
{
ProcessCompleted?.Invoke();
}
}
class Program
{
static void Main(string[] args)
{
ProcessBusinessLogic bl = new ProcessBusinessLogic();
bl.ProcessCompleted += Bl_ProcessCompleted; // 订阅事件
bl.StartProcess();
}
private static void Bl_ProcessCompleted()
{
Console.WriteLine("Process Completed!");
}
}
在这个例子中,当StartProcess
方法执行完毕时,会通过委托Notify
通知订阅者。
2、多播委托
多播委托可以引用多个方法,并且在调用时按顺序调用这些方法。这对于需要依次执行多个处理的场景非常有用。
using System;
public delegate void Notify(); // 声明委托
public class Program
{
public static void Main(string[] args)
{
Notify notify = Method1;
notify += Method2; // 订阅多个方法
notify();
}
public static void Method1()
{
Console.WriteLine("Method1 invoked.");
}
public static void Method2()
{
Console.WriteLine("Method2 invoked.");
}
}
在这个例子中,notify
委托依次调用Method1
和Method2
。
3、匿名方法和Lambda表达式
委托可以结合匿名方法和Lambda表达式使用,使代码更加简洁和灵活。
using System;
public delegate void Print(int value);
public class Program
{
public static void Main(string[] args)
{
Print print = delegate(int val) {
Console.WriteLine("Anonymous method: {0}", val);
};
print(100);
print = (val) => Console.WriteLine("Lambda expression: {0}", val);
print(200);
}
}
在这个例子中,使用匿名方法和Lambda表达式定义委托的实现方式,使代码更加简洁。
4、事件处理
委托是事件处理的基础,通过委托可以实现事件的定义和处理。例如,在用户界面编程中,按钮的点击事件处理。
using System;
public class Button
{
public delegate void ClickHandler(object sender, EventArgs e);
public event ClickHandler Click;
public void OnClick(EventArgs e)
{
Click?.Invoke(this, e);
}
}
public class Program
{
public static void Main(string[] args)
{
Button button = new Button();
button.Click += Button_Click;
button.OnClick(EventArgs.Empty);
}
private static void Button_Click(object sender, EventArgs e)
{
Console.WriteLine("Button clicked!");
}
}
在这个例子中,Button
类定义了Click
事件,通过委托ClickHandler
处理点击事件。
5、函数式编程
委托允许将函数作为对象处理,使得C#能够支持一定程度的函数式编程。例如,LINQ(Language Integrated Query)大量使用了委托和Lambda表达式。
using System;
using System.Linq;
using System.Collections.Generic;
public class Program
{
public static void Main(string[] args)
{
List<int> numbers = new List<int> { 1, 2, 3, 4, 5 };
List<int> evenNumbers = numbers.Where(n => n % 2 == 0).ToList();
evenNumbers.ForEach(n => Console.WriteLine(n));
}
}
在这个例子中,Where
方法接受一个委托Func<int, bool>
来筛选列表中的偶数。
总结
C#的委托从基本概念到匿名方法,再到Lambda表达式和泛型委托,其演变展示了语言的强大和灵活。
委托在回调、多播、事件处理以及函数式编程中的广泛应用,极大地增强了C#的功能和代码可维护性。
通过本文的示例,可以清晰地看到委托的实质性用途和在现代编程中的重要地位。
希望本文对大家有所收获,大家对委托有什么看法,欢迎留言讨论。
转自:莫小星
链接:mp.weixin.qq.com/s/93d5QW4LsC20G0v1re9bEw