IObserver 和 IObservable 在 C# 中用于观察者与委托、事件 [英] IObserver and IObservable in C# for Observer vs Delegates, Events

查看:22
本文介绍了IObserver 和 IObservable 在 C# 中用于观察者与委托、事件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我要做的就是实现观察者模式.

All I am trying to do is implementing the observer pattern.

所以,我想出了这个解决方案:

So, I came up with this solution:

我们有一个 PoliceHeadQuarters,其主要工作是向所有订阅它的人发送通知.假设 DSP、Inspector 和 SubInspector 类订阅了 PoliceHeadQuarters.

We have a PoliceHeadQuarters whose primary job is to send notifications to all those who are subscribed to it. Consider that the DSP, Inspector and SubInspector classes are subscribed to PoliceHeadQuarters.

使用我写的事件和委托

public class HeadQuarters 
{
    public delegate void NewDelegate(object sender, EventArgs e);
    public event EventHandler NewEvent;
    public void RaiseANotification()
    {
        var handler = this.NewEvent;
        if (handler != null)
        {
            handler(this, new EventArgs());
        }
    }
}

public class SubInspector
{
    public void Listen(object sender, EventArgs e)
    {
        MessageBox.Show(string.Format("Event Notification received by sender = {0} with eventArguments = {1}", sender, e.ToString()));
    }
}

public class Inspector
{
    public void Listen(object sender, EventArgs e)
    {
        MessageBox.Show(string.Format("Event Notification received by sender = {0} with eventArguments = {1}", sender, e.ToString()));
    }
}

这就是我调用它的方式

       var headQuarters = new HeadQuarters();
        var SubInspector = new SubInspector();
        var Inspector = new Inspector();
        headQuarters.NewEvent += Inspector.Listen;
        headQuarters.NewEvent += SubInspector.Listen;
        headQuarters.RaiseANotification();

因此,每当调用函数 RaiseANotification() 时,Inspector 和 SubInspector 类都会收到通知.

so, both Inspector and SubInspector classes get notification whenever there the function RaiseANotification() is invoked.

DotNet Framework 4, 4.5 似乎支持了一种新的方式,称为 IObserver 和 IObservable.

It seems that the DotNet Framework 4, 4.5 supports a new way called IObserver and IObservable.

谁能给我一个使用 IObservable 和 IObserver 模式用于上述场景的超级简单示例?我用谷歌搜索只是发现互联网上的可用示例过于臃肿且难以理解.

Can anyone give me a super simple example using IObservable and IObserver pattern for the above scenario? I googled only to find the available examples in the internet too bloated and difficult to understand.

我的想法:(可能我认为这是错误的)

My hinch: (probably i think it's wrong)

  class DSP : IObserver //since it observes the headquarters ?
  class PoliceHeadQuarters: IObservable // since here's where we send the notifications ?

提前致谢.

有人还说 MSDN 文档对于 IObservable @ 也不正确IObservable 与普通事件或为什么我应该使用 IObservable?.

Somebody also said that the MSDN documentation is also incorrect for IObservable @ IObservable vs Plain Events or Why Should I use IObservable?.

推荐答案

这是 MSDN 示例的修改以适合您的框架:

Here's a modification of MSDN example to fit your framework:

    public struct Message
    {
        string text;

        public Message(string newText)
        {
            this.text = newText;
        }

        public string Text
        {
            get
            {
                return this.text;
            }
        }
    }

    public class Headquarters : IObservable<Message>
    {
        public Headquarters()
        {
            observers = new List<IObserver<Message>>();
        }

        private List<IObserver<Message>> observers;

        public IDisposable Subscribe(IObserver<Message> observer)
        {
            if (!observers.Contains(observer))
                observers.Add(observer);
            return new Unsubscriber(observers, observer);
        }

        private class Unsubscriber : IDisposable
        {
            private List<IObserver<Message>> _observers;
            private IObserver<Message> _observer;

            public Unsubscriber(List<IObserver<Message>> observers, IObserver<Message> observer)
            {
                this._observers = observers;
                this._observer = observer;
            }

            public void Dispose()
            {
                if (_observer != null && _observers.Contains(_observer))
                    _observers.Remove(_observer);
            }
        }

        public void SendMessage(Nullable<Message> loc)
        {
            foreach (var observer in observers)
            {
                if (!loc.HasValue)
                    observer.OnError(new MessageUnknownException());
                else
                    observer.OnNext(loc.Value);
            }
        }

        public void EndTransmission()
        {
            foreach (var observer in observers.ToArray())
                if (observers.Contains(observer))
                    observer.OnCompleted();

            observers.Clear();
        }
    }

    public class MessageUnknownException : Exception
    {
        internal MessageUnknownException()
        {
        }
    }

    public class Inspector : IObserver<Message>
    {
        private IDisposable unsubscriber;
        private string instName;

        public Inspector(string name)
        {
            this.instName = name;
        }

        public string Name
        {
            get
            {
                return this.instName;
            }
        }

        public virtual void Subscribe(IObservable<Message> provider)
        {
            if (provider != null)
                unsubscriber = provider.Subscribe(this);
        }

        public virtual void OnCompleted()
        {
            Console.WriteLine("The headquarters has completed transmitting data to {0}.", this.Name);
            this.Unsubscribe();
        }

        public virtual void OnError(Exception e)
        {
            Console.WriteLine("{0}: Cannot get message from headquarters.", this.Name);
        }

        public virtual void OnNext(Message value)
        {
            Console.WriteLine("{1}: Message I got from headquarters: {0}", value.Text, this.Name);
        }

        public virtual void Unsubscribe()
        {
            unsubscriber.Dispose();
        }
    }

    public class Program
    {
        public static void Main(string[] args)
        {
            Inspector inspector1 = new Inspector("Greg Lestrade");
            Inspector inspector2 = new Inspector("Sherlock Holmes");

            Headquarters headquarters = new Headquarters();

            inspector1.Subscribe(headquarters);
            inspector2.Subscribe(headquarters);

            headquarters.SendMessage(new Message("Catch Moriarty!"));
            headquarters.EndTransmission();

            Console.ReadKey();
        }
    }

这篇关于IObserver 和 IObservable 在 C# 中用于观察者与委托、事件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆