C#观察者/观察与代表的超级简单的例子
我最近开始深入研究C#,但是我无法弄清楚在实现观察者/可观察模式的情况下代理是如何工作的。
有人能给我一个超级简单的例子吗? 我已经使用了这个,但是我发现的所有例子都是特定问题或太“臃肿”的。
观察者模式通常用事件来实现。
这是一个例子:
using System; class Observable { public event EventHandler SomethingHappened; public void DoSomething() { EventHandler handler = SomethingHappened; if (handler != null) { handler(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(); } }
查看链接的文章了解更多的细节。
这是一个简单的例子:
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; } }
注意:
- 这违反了一个规则,我不会从观察者中解开观察者,这对于这个简单的例子来说可能是足够好的,但是要确保你不要让观察者像这样把事件挂起来。 处理这种情况的方法是使ObserverClass IDisposable,并让.Dispose方法与构造函数中的代码相反
- 没有进行错误检查,至less应该在ObserverClass的构造函数中进行空检查
在这个模型中,你有发布者会做一些逻辑并发布一个“事件”。
然后,发布者将发送他们的事件给订阅了特定事件的订阅者。
在C#中,任何对象都可以发布其他应用程序可以订阅的一组事件。
当发布类引发事件时,通知所有订阅的应用程序。
下图显示了这种机制。
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 ie 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听到它
听众倾听它。 。 。 (无限次)
我已经把上面几个很好的例子(感谢Skeet先生和Karlsen先生 )包括在一起,包括一些不同的Observable,并利用一个接口在Observer中跟踪它们,并允许Observer通过一个内部列表“观察”任意数量的观测数据:
namespace ObservablePattern { using System; using System.Collections.Generic; internal static class Program { private static void Main() { var observable = new Observable(); var anotherObservable = new AnotherObservable(); using (IObserver observer = new Observer(observable)) { observable.DoSomething(); observer.Add(anotherObservable); anotherObservable.DoSomething(); } Console.ReadLine(); } } internal interface IObservable { event EventHandler SomethingHappened; } internal sealed class Observable : IObservable { public event EventHandler SomethingHappened; public void DoSomething() { var handler = this.SomethingHappened; Console.WriteLine("About to do something."); if (handler != null) { handler(this, EventArgs.Empty); } } } internal sealed class AnotherObservable : IObservable { public event EventHandler SomethingHappened; public void DoSomething() { var handler = this.SomethingHappened; Console.WriteLine("About to do something different."); if (handler != null) { handler(this, EventArgs.Empty); } } } internal interface IObserver : IDisposable { void Add(IObservable observable); void Remove(IObservable observable); } internal sealed class Observer : IObserver { private readonly Lazy<IList<IObservable>> observables = new Lazy<IList<IObservable>>(() => new List<IObservable>()); public Observer() { } public Observer(IObservable observable) : this() { this.Add(observable); } public void Add(IObservable observable) { if (observable == null) { return; } lock (this.observables) { this.observables.Value.Add(observable); observable.SomethingHappened += HandleEvent; } } public void Remove(IObservable observable) { if (observable == null) { return; } lock (this.observables) { observable.SomethingHappened -= HandleEvent; this.observables.Value.Remove(observable); } } public void Dispose() { for (var i = this.observables.Value.Count - 1; i >= 0; i--) { this.Remove(this.observables.Value[i]); } } private static void HandleEvent(object sender, EventArgs args) { Console.WriteLine("Something happened to " + sender); } } }
查看Rx Framework的介绍,该介绍使用美妙的IObserver-IObservable非阻塞asynchronous编程模型介绍了rx-linq-to-events
在c#中使用带有委托和事件的观察者模式根据MSDN命名为“事件模式” ,这是一个小的变化。
在这篇文章中,您将find如何在c#中使用模式以及使用委托和事件的结构化示例。
探索观察者devise模式
public class Stock { //declare a delegate for the event public delegate void AskPriceChangedHandler(object sender, AskPriceChangedEventArgs e); //declare the event using the delegate public event AskPriceChangedHandler AskPriceChanged; //instance variable for ask price object _askPrice; //property for ask price public object AskPrice { set { //set the instance variable _askPrice = value; //fire the event OnAskPriceChanged(); } }//AskPrice property //method to fire event delegate with proper name protected void OnAskPriceChanged() { AskPriceChanged(this, new AskPriceChangedEventArgs(_askPrice)); }//AskPriceChanged }//Stock class //specialized event class for the askpricechanged event public class AskPriceChangedEventArgs : EventArgs { //instance variable to store the ask price private object _askPrice; //constructor that sets askprice public AskPriceChangedEventArgs(object askPrice) { _askPrice = askPrice; } //public property for the ask price public object AskPrice { get { return _askPrice; } } }//AskPriceChangedEventArgs
/**********************Simple Example ***********************/ class Program { static void Main(string[] args) { Parent p = new Parent(); } } //////////////////////////////////////////// public delegate void DelegateName(string data); class Child { public event DelegateName delegateName; public void call() { delegateName("Narottam"); } } /////////////////////////////////////////// class Parent { public Parent() { Child c = new Child(); c.delegateName += new DelegateName(print); //or like this //c.delegateName += print; c.call(); } public void print(string name) { Console.WriteLine("yes we got the name : " + name); } }
我不想改变我的源代码来添加额外的观察者,所以我写了以下简单的例子:
//EVENT DRIVEN OBSERVER PATTERN public class Publisher { public Publisher() { var observable = new Observable(); observable.PublishData("Hello World!"); } } //Server will send data to this class's PublishData method public class Observable { public event Receive OnReceive; public void PublishData(string data) { //Add all the observer below //1st observer IObserver iObserver = new Observer1(); this.OnReceive += iObserver.ReceiveData; //2nd observer IObserver iObserver2 = new Observer2(); this.OnReceive += iObserver2.ReceiveData; //publish data var handler = OnReceive; if (handler != null) { handler(data); } } } public interface IObserver { void ReceiveData(string data); } //Observer example public class Observer1 : IObserver { public void ReceiveData(string data) { //sample observers does nothing with data :) } } public class Observer2 : IObserver { public void ReceiveData(string data) { //sample observers does nothing with data :) } }
像这样的东西:
// interface implementation publisher public delegate void eiSubjectEventHandler(eiSubject subject); public interface eiSubject { event eiSubjectEventHandler OnUpdate; void GenereteEventUpdate(); } // class implementation publisher class ecSubject : eiSubject { private event eiSubjectEventHandler _OnUpdate = null; public event eiSubjectEventHandler OnUpdate { add { lock (this) { _OnUpdate -= value; _OnUpdate += value; } } remove { lock (this) { _OnUpdate -= value; } } } public void GenereteEventUpdate() { eiSubjectEventHandler handler = _OnUpdate; if (handler != null) { handler(this); } } } // interface implementation subscriber public interface eiObserver { void DoOnUpdate(eiSubject subject); } // class implementation subscriber class ecObserver : eiObserver { public virtual void DoOnUpdate(eiSubject subject) { } }
。 观察者模式C#与事件 。 链接到存储库