背景#
假設我們有一個 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));