C#观察者/可观察者与代表的超级简单示例

C#观察者/可观察者与代表的超级简单示例,c#,events,delegates,observer-pattern,C#,Events,Delegates,Observer Pattern,我最近开始钻研C#,但我一生都搞不清楚在语言中实现观察者/可观察模式时委托是如何工作的 有人能给我一个超级简单的例子来说明它是如何做到的吗?我已经在谷歌上搜索过了,但我发现的所有示例要么太具体,要么太“臃肿”。观察者模式通常是通过 下面是一个例子: using System; class Observable { public event EventHandler SomethingHappened; public void DoSomething() =>

我最近开始钻研C#,但我一生都搞不清楚在语言中实现观察者/可观察模式时委托是如何工作的


有人能给我一个超级简单的例子来说明它是如何做到的吗?我已经在谷歌上搜索过了,但我发现的所有示例要么太具体,要么太“臃肿”。

观察者模式通常是通过

下面是一个例子:

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();
    }
}
有关更多详细信息,请参阅链接文章

请注意,上面的示例使用C#6 null条件运算符安全地实现
DoSomething
,以处理
somethingOccessed
尚未订阅的情况,因此为null。如果您使用的是较旧版本的C#,则需要以下代码:

public void DoSomething()
{
    var handler = SomethingHappened;
    if (handler != null)
    {
        handler(this, EventArgs.Empty);
    }
}

下面是一个简单的例子:

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;
    }
}
//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 :)
    }
}
注:

  • 这违反了一条规则,即我不会将观察者与可观察者分开,对于这个简单的例子来说,这可能已经足够好了,但请确保不要让观察者像那样挂断你的事件。处理此问题的一种方法是使observer类IDisposable,并让.Dispose方法执行与构造函数中的代码相反的操作
  • 未执行错误检查,至少应在ObserverClass的构造函数中执行空检查

我将上面几个很好的例子结合在一起(感谢您一直以来的和),以包括两个不同的观察对象,并利用一个界面在观察者中跟踪它们,并允许观察者通过内部列表“观察”任意数量的观察对象:

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);
        }
    }
}
命名空间可观察模式
{
使用制度;
使用System.Collections.Generic;
内部静态类程序
{
私有静态void Main()
{
var可观测=新可观测();
var anotherObservable=新的anotherObservable();
使用(IObserver observer=新观察者(可观察))
{
可观察的。剂量测定法();
观察者。添加(另一个可观察的);
另一个可以观察到的。DoSomething();
}
Console.ReadLine();
}
}
内部接口可观察
{
事件处理程序发生了一些事情;
}
内部密封类可观察:IObservable
{
公共事件处理程序发生了什么事情;
公共无效剂量测定法()
{
var handler=this.something发生了什么事;
Console.WriteLine(“即将做某事”);
if(处理程序!=null)
{
处理程序(此,EventArgs.Empty);
}
}
}
内部密封类另一个可观察:IObservable
{
公共事件处理程序发生了什么事情;
公共无效剂量测定法()
{
var handler=this.something发生了什么事;
WriteLine(“即将做一些不同的事情”);
if(处理程序!=null)
{
处理程序(此,EventArgs.Empty);
}
}
}
内部接口IObserver:IDisposable
{
void Add(可观察到的);
空洞消除(可观察到);
}
内部密封类观察者:IObserver
{
私有只读惰性观测值=
新建延迟(()=>newlist());
公众观察员()
{
}
公共观察者(IObservable-observable):this()
{
这个。添加(可观察);
}
公共无效添加(IObservable-observable)
{
if(可观察==null)
{
返回;
}
锁(这是可观察的)
{
这个。可观察的。价值。增加(可观察的);
可观察到的。发生了什么事+=HandleEvent;
}
}
公共无效删除(IObservable-observable)
{
if(可观察==null)
{
返回;
}
锁(这是可观察的)
{
可观察到的,可观察到的,可观察到的;
这个。可观察的。值。移除(可观察的);
}
}
公共空间处置()
{
对于(var i=this.observables.Value.Count-1;i>=0;i--)
{
移除(这个可观测值[i]);
}
}
私有静态void HandleEvent(对象发送方、事件args args)
{
Console.WriteLine(“发生了一些事情”+发送方);
}
}
}

我不想更改源代码来添加额外的观察者,因此我编写了以下简单示例:

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;
    }
}
//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 :)
    }
}
大概是这样的:

public void DoSomething()
{
    var handler = SomethingHappened;
    if (handler != null)
    {
        handler(this, EventArgs.Empty);
    }
}
//接口实现发布器
公共委托void eiSubjectEventHandler(eiSubject主题);
公共接口eiSubject
{
事件eiSubjectEventHandler OnUpdate;
void generateEventUpdate();
}
//类实现发布器
类主题:eiSubject
{
私有事件eiSubjectEventHandler _OnUpdate=null;
公共事件eiSubjectEventHandler OnUpdate
{
添加
{
锁(这个)
{
_OnUpdate-=值;
_OnUpdate+=值;
}
}
删除{lock(this){u OnUpdate-=value;}}
}
public void generateEventUpdate()
{
eiSubjectEventHandler=\u OnUpdate;
if(处理程序!=null)
{
处理者(本);
}
}
}
//接口实现订户
公共接口eiObserver
{
void DoOnUpdate(eiSubject主题);
}
//类实现订户
类ecoobserver:eiObserver
{
公共虚拟虚空DoOnUpdate(eiSubject主题)
{
}
}
。 .
根据MSDN的规定,将观察者模式应用于c#中的代表和事件,将其命名为“事件模式”,这是一个细微的变化