在C#中,委托(delegate)是一种引用类型,在其他语言中,与委托最接近的是函数指针,但委托不仅存储对方法入口点的引用,还存储对用于调用方法的对象实例的引用。MSDN地址http://msdn.microsoft.com/zh-cn/library/ms173171
1、定义并使用委托
模拟一个控制器,通过控制器能够安全的使用下面方法把机器关闭。
(1)、用方法实现
class Controller { private FoldingMachine folder; private WeldingMachine welder; private PaintingMachine painter; public void ShutDown() { folder.StopFolding(); welder.FinishWelding(); painter.PaintOff(); } }
(2)、使用委托
定义并使用委托
class Controller { delegate void stopMachineryDelegate();//定义委托 private stopMachineryDelegate stopMachinery;//声明变量 public Controller() { this.stopMachinery +=folder.StopFolding; //相当于对声明的委托变量实例化操作 //this.stopMachinery =new stopMachineryDelegate(folder.StopFolding); } }
调用委托
public void shutDown() { this.stopMachinery(); }
完整列子
class Program { static void Main(string[] args) { FoldingMachine folder = new FoldingMachine(); WeldingMachine welder = new WeldingMachine(); PaintingMachine painter = new PaintingMachine(); Controller controller = new Controller(); controller.Folder = folder; controller.Welder = welder; controller.Painter = painter; //controller.stopManchinery += folder.StopFolding; //controller.StopManchinery = folder.StopFolding; //controller.StopManchinery = welder.FinishWelding; //controller.Add(folder.FinishFolding); controller.Add(() => { folder.StopFolding(0); });//lambda表达式 controller.Add(welder.FinishWelding);//调用委托 //controller.Remove(folder.StopFolding); //controller.ShutDown(); controller.StopManchinery(); } }
class Controller { private FoldingMachine folder; private WeldingMachine welder; private PaintingMachine painter; public delegate void stopManchineryDelegate();//定义委托类型 public stopManchineryDelegate stopManchinery;//声明委托变量 public Controller() { } public stopManchineryDelegate StopManchinery { get { return stopManchinery; } set { stopManchinery += value; } } public void Add(stopManchineryDelegate stopMethod)//实例化委托 { stopManchinery += stopMethod; } public void Remove(stopManchineryDelegate stopMethod) { stopManchinery -= stopMethod; } public void SetStopManchinery() { //stopManchinery = new stopManchineryDelegate(folder.StopFolding); //stopManchinery += folder.StopFolding; //stopManchinery += welder.FinishWelding; stopManchinery += painter.PaintOff;//委托指向一个方法 stopManchinery -= welder.FinishWelding;//从委托中移除方法 } public void ShutDown() { //folder.StopFolding(); //welder.FinishWelding(); //painter.PaintOff(); //SetStopManchinery(); stopManchinery(); } public FoldingMachine Folder { set { this.folder = value; } } public WeldingMachine Welder { set { this.welder = value; } } public PaintingMachine Painter { set { this.painter = value; } } }
Clock例子
LocalClock.cs using System; using System.Windows.Controls; using System.Windows.Threading; using System.Timers; namespace Delegates { class LocalClock { private DispatcherTimer ticker = null; //private TextBox display = null; private TimeZoneInfo timeZoneForThisClock = null; public delegate void DisplayTime(string time); public event DisplayTime LocalClockTick; public LocalClock() { this.timeZoneForThisClock = TimeZoneInfo.Local; //this.display = displayBox; } public void StartLocalClock() { this.ticker = new DispatcherTimer(); this.ticker.Tick += this.OnTimedEvent; this.ticker.Interval = new TimeSpan(0, 0, 1); // 1 second this.ticker.Start(); } public void StopLocalClock() { this.ticker.Stop(); } private void OnTimedEvent(object source, EventArgs args) { DateTime localTime = DateTime.Now; DateTime clockTIme = TimeZoneInfo.ConvertTime(localTime, this.timeZoneForThisClock); int hh = clockTIme.Hour; int mm = clockTIme.Minute; int ss = clockTIme.Second; this.RefreshTime(hh, mm, ss); } private void RefreshTime(int hh, int mm, int ss) { //this.display.Text = string.Format("{0:D2}:{1:D2}:{2:D2}", hh, mm, ss); if (this.LocalClockTick != null) { this.LocalClockTick(String.Format("{0:D2}:{1:D2}:{2:D2}",hh,mm,ss)); } } } }
JapaneseClock.cs using System; using System.Windows.Controls; using System.Windows.Threading; using System.Timers; namespace Delegates { class JapaneseClock { private DispatcherTimer ticker = null; private TextBox display = null; private TimeZoneInfo timeZoneForThisClock = null; private const string tokyoTimeZoneId = "Tokyo Standard Time"; public JapaneseClock(TextBox displayBox) { this.timeZoneForThisClock = TimeZoneInfo.FindSystemTimeZoneById(tokyoTimeZoneId); this.display = displayBox; } public void StartJapaneseClock() { this.ticker = new DispatcherTimer(); this.ticker.Tick += this.OnTimedEvent; this.ticker.Interval = new TimeSpan(0, 0, 1); // 1 second this.ticker.Start(); } public void StopJapaneseClock() { this.ticker.Stop(); } private void OnTimedEvent(object source, EventArgs args) { DateTime localTime = DateTime.Now; DateTime clockTIme = TimeZoneInfo.ConvertTime(localTime, this.timeZoneForThisClock); int hh = clockTIme.Hour; int mm = clockTIme.Minute; int ss = clockTIme.Second; this.RefreshTime(hh, mm, ss); } private void RefreshTime(int hh, int mm, int ss) { this.display.Text = string.Format("{0:D2}:{1:D2}:{2:D2}", hh, mm, ss); } } }
Controller.cs using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Delegates { class Controller { public delegate void StartClocksDelegate(); public delegate void StopClocksDelegate(); public StartClocksDelegate StartClocks; public StopClocksDelegate StopClocks; public void StartClocksRunning() { this.StartClocks(); } public void StopClocksRunning() { this.StopClocks(); } } }
ClockWindow.xaml using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; namespace Delegates { public partial class ClockWindow : Window { private LocalClock localClock = null; private EuropeanClock londonClock = null; private AmericanClock newYorkClock = null; private JapaneseClock tokyoClock = null; private Controller controller = new Controller(); public ClockWindow() { InitializeComponent(); //localClock = new LocalClock(localTimeDisplay); localClock = new LocalClock(); londonClock = new EuropeanClock(londonTimeDisplay); newYorkClock = new AmericanClock(newYorkTimeDisplay); tokyoClock = new JapaneseClock(tokyoTimeDisplay); controller.StartClocks += localClock.StartLocalClock; controller.StartClocks += londonClock.StartEuropeanClock; controller.StartClocks += newYorkClock.StartAmericanClock; controller.StartClocks += tokyoClock.StartJapaneseClock; controller.StopClocks += localClock.StopLocalClock; controller.StopClocks += londonClock.StopEuropeanClock; controller.StopClocks += newYorkClock.StopAmericanClock; controller.StopClocks += tokyoClock.StopJapaneseClock; } private void startClick(object sender, RoutedEventArgs e) { controller.StartClocks(); localClock.LocalClockTick += displayLocalTime; start.IsEnabled = false; stop.IsEnabled = true; } private void stopClick(object sender, RoutedEventArgs e) { controller.StopClocks(); localClock.LocalClockTick -= displayLocalTime; start.IsEnabled = true; stop.IsEnabled = false; } private void displayLocalTime(string time) { localTimeDisplay.Text = time; } } }