3 回答

TA貢獻(xiàn)1804條經(jīng)驗(yàn) 獲得超2個贊
觀察者模式通常通過事件來實(shí)現(xiàn)。
這是一個例子:
using System;
class Observable
{
public event EventHandler SomethingHappened;
public void DoSomething() =>
SomethingHappened?.Invoke(this, EventArgs.Empty);
}
class Observer
{
public void HandleEvent(object sender, EventArgs args)
{
Console.WriteLine("Something happened to " + sender);
}
}
class Test
{
static void Main()
{
Observable observable = new Observable();
Observer observer = new Observer();
observable.SomethingHappened += observer.HandleEvent;
observable.DoSomething();
}
}
有關(guān)更多詳細(xì)信息,請參見鏈接的文章。
請注意,上面的示例使用C#6 空條件運(yùn)算符來DoSomething安全地實(shí)現(xiàn)以處理SomethingHappened尚未訂閱的情況,因此為null。如果您使用的是舊版本的C#,則需要這樣的代碼:
public void DoSomething()
{
var handler = SomethingHappened;
if (handler != null)
{
handler(this, EventArgs.Empty);
}
}

TA貢獻(xiàn)1877條經(jīng)驗(yàn) 獲得超1個贊
這是一個簡單的示例:
public class ObservableClass
{
private Int32 _Value;
public Int32 Value
{
get { return _Value; }
set
{
if (_Value != value)
{
_Value = value;
OnValueChanged();
}
}
}
public event EventHandler ValueChanged;
protected void OnValueChanged()
{
if (ValueChanged != null)
ValueChanged(this, EventArgs.Empty);
}
}
public class ObserverClass
{
public ObserverClass(ObservableClass observable)
{
observable.ValueChanged += TheValueChanged;
}
private void TheValueChanged(Object sender, EventArgs e)
{
Console.Out.WriteLine("Value changed to " +
((ObservableClass)sender).Value);
}
}
public class Program
{
public static void Main()
{
ObservableClass observable = new ObservableClass();
ObserverClass observer = new ObserverClass(observable);
observable.Value = 10;
}
}
注意:
這違反了一個規(guī)則,即我不將觀察者從可觀察對象中解脫出來,對于這個簡單的示例來說,這也許就足夠了,但是請確保您不要讓觀察者脫離這樣的事件。解決此問題的一種方法是使ObserverClass IDisposable,并讓.Dispose方法執(zhí)行與構(gòu)造函數(shù)中的代碼相反的操作
不執(zhí)行錯誤檢查,至少應(yīng)在ObserverClass的構(gòu)造函數(shù)中進(jìn)行空檢查

TA貢獻(xiàn)1808條經(jīng)驗(yàn) 獲得超4個贊
在此模型中,您有一些發(fā)布者,他們將做一些邏輯并發(fā)布一個“事件”。
然后,發(fā)布者將僅向已訂閱接收特定事件的訂閱者發(fā)送事件。
在C#中,任何對象都可以發(fā)布其他應(yīng)用程序可以訂閱的一組事件。
當(dāng)發(fā)布類引發(fā)事件時,將通知所有訂閱的應(yīng)用程序。
下圖顯示了這種機(jī)制。
在此處輸入圖片說明
關(guān)于C#中事件和委托的最簡單示例:
代碼是不言自明的,此外,我還添加了注釋以清除代碼。
using System;
public class Publisher //main publisher class which will invoke methods of all subscriber classes
{
public delegate void TickHandler(Publisher m, EventArgs e); //declaring a delegate
public TickHandler Tick; //creating an object of delegate
public EventArgs e = null; //set 2nd paramter empty
public void Start() //starting point of thread
{
while (true)
{
System.Threading.Thread.Sleep(300);
if (Tick != null) //check if delegate object points to any listener classes method
{
Tick(this, e); //if it points i.e. not null then invoke that method!
}
}
}
}
public class Subscriber1 //1st subscriber class
{
public void Subscribe(Publisher m) //get the object of pubisher class
{
m.Tick += HeardIt; //attach listener class method to publisher class delegate object
}
private void HeardIt(Publisher m, EventArgs e) //subscriber class method
{
System.Console.WriteLine("Heard It by Listener");
}
}
public class Subscriber2 //2nd subscriber class
{
public void Subscribe2(Publisher m) //get the object of pubisher class
{
m.Tick += HeardIt; //attach listener class method to publisher class delegate object
}
private void HeardIt(Publisher m, EventArgs e) //subscriber class method
{
System.Console.WriteLine("Heard It by Listener2");
}
}
class Test
{
static void Main()
{
Publisher m = new Publisher(); //create an object of publisher class which will later be passed on subscriber classes
Subscriber1 l = new Subscriber1(); //create object of 1st subscriber class
Subscriber2 l2 = new Subscriber2(); //create object of 2nd subscriber class
l.Subscribe(m); //we pass object of publisher class to access delegate of publisher class
l2.Subscribe2(m); //we pass object of publisher class to access delegate of publisher class
m.Start(); //starting point of publisher class
}
}
輸出:
聽眾聽到
Listener2聽到了
聽眾聽到
Listener2聽到了
聽眾聽到。。。(無限次)
- 3 回答
- 0 關(guān)注
- 647 瀏覽
添加回答
舉報(bào)