背景#
假设我们有一个 Form,它依赖于单独的业务类,而我们又想在业务类中控制 Form 里面 UI 控件,比如更新进度条之类的,这时候就需要用到 delegate
(委托)。
delegate 就是包装了方法的引用,将引用作为参数传给其他方法,其它方法拿到引用后,就像调用方法一样去执行它。
这里为了简便,假设我们在业务中需要指定内容的弹窗。
定义委托#
创建一个 Global.cs
文件,在里面将委托和所需的参数定义好:
namespace WindowsFormsApp1
{
public class Global
{
// 定义一个带参数的委托
public delegate void CallBack(Data data);
}
public class Data
{
public string Name { get; set; }
}
}
BLL#
接着将委托作为参数传递给业务方法,在执行委托时:
using System.Threading.Tasks;
using static WindowsFormsApp1.Global;
namespace WindowsFormsApp1
{
public class BLL
{
public void SayHi(CallBack callback) =>
Task.Run(() => { callback(new Data { Name = "bob" }); });
}
}
Form#
接着需要在 Form 中初始化委托,并执行业务函数:
using System.Windows.Forms;
using static WindowsFormsApp1.Global;
namespace WindowsFormsApp1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
// 实例化委托,传入被委托的函数
var callback = new CallBack(AnyMethod);
// 指定业务逻辑
new BLL().SayHi(callback);
}
private void AnyMethod(Data data)
=> MessageBox.Show($"Hi, {data.Name}");
}
}
就好了。
优化#
C# 提供了两个封装好了的委托:
这样我们就不用自己去定义委托,所以我们改一下程序。
Global#
删除 Global
类。
BLL#
public void SayHi(Action<Data> callback)
Form#
new BLL().SayHi(new Action<Data>(AnyMethod));