有两个对象NOTIFIER和OBSERVER。 NOTIFIER不知道OBSERVER,而OBSERVER知道NOTIFIER实现了一个事件。
OBSERVER使用该事件通知其他对象发生了某些事情。简单地说,事件是一个方法列表。因为OBSERVER想在发生某些事情时得到通知,它将一个应该被调用的方法添加到NOTIFIER的事件中。
所以如果NOTIFIER使用此事件发布某些内容,NOTIFIER只需遍历方法列表并调用这些方法。当OBSERVER添加的方法被调用时,OBSERVER知道发生了某些事情,并且可以在这种情况下执行任何必要的操作。
这里是一个带有ValueChanged()事件的示例notifier类。
public delegate void ValueChangedHandler(Notifier sender, Int32 oldValue, Int32 newValue);
public class Notifier
{
public Notifier(String name)
{
this.Name = name;
}
public String Name { get; private set; }
public event ValueChangedHandler ValueChanged;
public void ChangeValue(Int32 newValue)
{
if (this.value != newValue)
{
Int32 oldValue = this.value;
this.value = newValue;
this.OnValueChanged(oldValue, newValue);
}
}
private Int32 value = 0;
private void OnValueChanged(Int32 oldValue, Int32 newValue)
{
ValueChangedHandler valueChangedHandler = this.ValueChanged;
if (valueChangedHandler != null)
{
valueChangedHandler(this, oldValue, newValue);
}
}
}
这是一个观察者类的示例。
public class Observer
{
public Observer(String name)
{
this.Name = name;
}
public String Name { get; private set; }
public void NotifierValueChanged(Notifier sender, Int32 oldValue, Int32 newValue)
{
Console.WriteLine(String.Format("{0}: The value of {1} changed from {2} to {3}.", this.Name, sender.Name, oldValue, newValue));
}
}
一个小的测试应用程序。
class Program
{
static void Main(string[] args)
{
Notifier notifierA = new Notifier("Notifier A");
Notifier notifierB = new Notifier("Notifier B");
Observer observerX = new Observer("Observer X");
Observer observerY = new Observer("Observer Y");
notifierA.ValueChanged += observerX.NotifierValueChanged;
notifierA.ValueChanged += observerY.NotifierValueChanged;
notifierB.ValueChanged += observerY.NotifierValueChanged;
notifierA.ChangeValue(123);
notifierB.ChangeValue(999);
notifierA.ChangeValue(123);
notifierA.ChangeValue(1);
}
}
输出结果如下:
观察者X:Notifier A的值从0变为123。
观察者Y:Notifier A的值从0变为123。
观察者Y:Notifier B的值从0变为999。
观察者X:Notifier A的值从123变为1。
观察者Y:Notifier A的值从123变为1。
为了理解委托类型,我将与类类型进行比较。
public class Example
{
public void DoSomething(String text)
{
Console.WriteLine(
"Doing something with '" + text + "'.");
}
public void DoSomethingElse(Int32 number)
{
Console.WriteLine(
"Doing something with '" + number.ToString() + "'.");
}
}
我们定义了一个简单的类 Example
,它有两个方法。现在我们可以使用这个类类型。
Example example = new Example()
虽然这种方法可行,但以下方法不可行,因为类型不匹配。您会收到编译器错误提示。
Example example = new List<String>()
我们可以使用变量example
。
example.DoSomething("some text");
现在使用委托类型做同样的事情。首先,我们定义一个委托类型 - 这只是类定义之前的类型定义。
public delegate void MyDelegate(String text);
现在我们可以使用委托类型,但我们不能将普通数据存储在委托类型变量中,而是必须存储一个方法。
MyDelegate method = example.DoSomething;
我们现在已经存储了对象example
的方法DoSomething()
。下面的内容无法工作,因为我们将MyDelegate
定义为一个只有一个字符串参数并返回void的委托。 DoSomethingElse
返回void但需要一个整数参数,所以你会得到编译器错误。
MyDelegate method = example.DoSomethingElse;
最后,您可以使用变量method
。由于该变量存储的是方法而不是数据,因此无法执行数据操作。但是您可以调用存储在变量中的方法。
method("Doing stuff with delegates.");
这会调用我们存储在变量中的方法 - example.DoSomething()
。