Skip to content

委托和事件

L edited this page Mar 19, 2020 · 5 revisions

摘抄自C# 中的委托和事件

委托

委托是一个类,它定义了方法的类型,使得可以将方法当作另一个方法的参数来进行传递,这种将方法动态地赋给参数的做法,可以避免在程序中大量使用If-Else(Switch)语句,同时使得程序具有更好的可扩展性。
使用委托可以将多个方法绑定到同一个委托变量,当调用此变量时(这里用“调用”这个词,是因为此变量代表一个方法),可以依次调用所有绑定的方法。

static void Main(string[] args) {
    GreetingDelegate delegate1 = new GreetingDelegate(EnglishGreeting);
    delegate1 += ChineseGreeting;   // 给此委托变量再绑定一个方法

    // 将先后调用 EnglishGreeting 与 ChineseGreeting 方法
    GreetPeople("Jimmy Zhang", delegate1); 
    Console.WriteLine();

    delegate1 -= EnglishGreeting; //取消对EnglishGreeting方法的绑定
    // 将仅调用 ChineseGreeting
    GreetPeople("张子阳", delegate1);
    Console.ReadKey();
}
输出为:
Morning, Jimmy Zhang
早上好, Jimmy Zhang
早上好, 张子阳

事件

Event封装了委托类型的变量,使得:在类的内部,它总是private的。在类的外部,通过AddEvenetRemoveEvent来操纵委托变量。 声明一个事件不过类似于声明一个进行了封装的委托类型的变量而已。

public class GreetingManager
{
	public delegate void GreetingDelegate(string name);
	private GreetingDelegate MakeGreet { get; set; }

	public void GreetPeople(string name)
	{
		if (MakeGreet != null)
		{
			MakeGreet(name);
		}
	}

	[MethodImpl(MethodImplOptions.Synchronized)]
	public void AddMakeGreet(GreetingDelegate value)
	{
		this.MakeGreet = (GreetingDelegate)System.Delegate.Combine(this.MakeGreet, value);
	}

	[MethodImpl(MethodImplOptions.Synchronized)]
	public void RemoveMakeGreet(GreetingDelegate value)
	{
		this.MakeGreet = (GreetingDelegate)System.Delegate.Remove(this.MakeGreet, value);
	}
}
public class EventDemo
{
	private static void EnglishGreeting(string name)
	{
		Console.WriteLine("Morning, " + name);
	}

	private static void ChineseGreeting(string name)
	{
		Console.WriteLine("早上好, " + name);
	}

	public static void Run()
	{
		GreetingManager GreetingManager = new GreetingManager();
		GreetingManager.AddMakeGreet(EnglishGreeting);
		GreetingManager.AddMakeGreet(ChineseGreeting);
		GreetingManager.GreetPeople("Lulu");
	}
}

假设我们有个高档的热水器,我们给它通上电,当水温超过95度的时候:
1、扬声器会开始发出语音,告诉你水的温度;
2、液晶屏也会改变水温的显示,来提示水已经快烧开了。

Observer设计模式

Observer设计模式(观察者模式)中主要包括如下两类对象:
Subject:监视对象,它往往包含着其他对象所感兴趣的内容。在本范例中,热水器就是一个监视对象,它包含的其他对象所感兴趣的内容,就是temprature字段,当这个字段的值快到100时,会不断把数据发给监视它的对象。
Observer:监视者,它监视Subject,当Subject中的某件事发生的时候,会告知Observer,而Observer则会采取相应的行动。在本范例中,Observer有警报器和显示器,它们采取的行动分别是发出警报和显示水温。
在本例中,事情发生的顺序应该是这样的:
警报器和显示器告诉热水器,它对它的温度感兴趣(注册)。
热水器知道后保留对警报器和显示器的引用。
热水器进行烧水这一动作,当水温超过95度时,通过对警报器和显示器的引用,自动调用警报器的MakeAlert()方法、显示器的ShowMsg()方法。
类似这样的例子是很多的,GOF对它进行了抽象,称为Observer设计模式:Observer设计模式是为了定义对象间的一种一对多的依赖关系,以便于当一个对象的状态改变时,其他依赖于它的对象会被自动告知并更新。Observer模式是一种松耦合的设计模式。

示例代码

DelegateAndEvent

参考资料

C# 委托(Delegate)
C# 事件(Event)
c#中委托和事件?

Clone this wiki locally