Multiple generic event publishers? - c#

I have this simple interface:
public interface IEventPublisher<T>
{
public delegate void EventHandler(T report);
public event EventHandler OnEventReceived;
}
Then I can write a class to subscribe to events of type int and string:
public class Subscriber
{
public Subscriber(IEventPublisher<int> intPublisher, IEventPublisher<string> stringPublisher)
{
intPublisher.OnEventReceived += OnIntEventReceived;
stringPublisher.OnEventReceived += OnStringEventReceived;
}
private void OnIntEventReceived(int report)
{
}
private void OnStringEventReceived(string report)
{
}
}
Now comes the challenge: I would like to write a class to be a publisher of events of type int and string, so I start with:
public class Publisher : IEventPublisher<int>, IEventPublisher<string>
{
}
How do I implement this in order to satisfy both interfaces? The problem is that the event handler names are identical (OnEventReceived).
This is how I would have written it for a publisher just implementing one of the interfaces:
public interface IEventPublisher<T>
{
public delegate void EventHandler(T report);
public event EventHandler OnEventReceived;
}
public class Subscriber
{
public Subscriber(IEventPublisher<int> intPublisher)
{
intPublisher.OnEventReceived += OnIntEventReceived;
}
private void OnIntEventReceived(int report)
{
}
}
public class Publisher : IEventPublisher<int>
{
public event IEventPublisher<int>.EventHandler? OnEventReceived;
public Publisher()
{
Subscriber subscriber = new Subscriber(this);
}
private void GenerateEvents()
{
while (true)
{
...
OnEventReceived?.Invoke(number);
}
}
}

Did you try it? My IDE (with ReSharper) gives this implementation:
public class Publisher : IEventPublisher<int>, IEventPublisher<string>
{
event IEventPublisher<int>.EventHandler? IEventPublisher<int>.OnEventReceived
{
add
{
// Your code here.
}
remove
{
// Your code here.
}
}
event IEventPublisher<string>.EventHandler? IEventPublisher<string>.OnEventReceived
{
add
{
// Your code here.
}
remove
{
// Your code here.
}
}
}
And the Subscriber class would subscribe like this.
public class Subscriber
{
public Subscriber()
{
var publisher = new Publisher();
IEventPublisher<int> intPublisher = publisher;
IEventPublisher<string> stringPublisher = publisher;
intPublisher.OnEventReceived += OnIntEventReceived;
stringPublisher.OnEventReceived += OnStringEventReceived;
}
private void OnIntEventReceived(int report)
{
}
private void OnStringEventReceived(string report)
{
}
}
Note: I haven't actually tried compiling/running this.

Related

Why does event remain null even after subscribing to it?

I have classes Room and Iceball. Iceball and IceShard are inherited from class Magic.
When I add new magic to room, room subscribes to event CreateNewMagic magic, but after exiting from method event is still null.
Iceball after collision should creates ice shards in the room with the help of event, but because the event is null room cant spawn ice shards
Class Room
{
public readonly List<Magi> MagicInRoom;
public void SpawnMagic(Magic magic)
{
MagicInRoom.Add(magic);
magic.CreateNewMagic += SpawnMagic;
}
}
Class Magic, IceBall and IceShard
public abstract class Magic
{
public delegate void MagicHandler(Magic magic);
public event MagicHandler CreateNewMagic;
public virtual void OnCollisionEnter()
{
if (...)
{
...
}
}
}
public class IceBall : Magic
{
public delegate void MagicHandler(Magic magic);
public event MagicHandler CreateNewMagic;
public override void OnCollisionEnter()
{
if (...)
{
var iceShards = CreateIceShards();
foreach (var iceShard in iceShards)
if (CreateNewMagic != null) //ALWAYS IS NULL
CreateNewMagic(iceShard);
}
}
}
public class IceShard : Magic
{
...
}
Event should be abstract
public abstract class Magic
{
public delegate void MagicHandler(Magic magic);
public abstract event MagicHandler CreateNewMagic;
public virtual void OnCollisionEnter()
{
if (...)
{
...
}
}
}
public class IceBall : Magic
{
public override event MagicHandler CreateNewMagic;
public override void OnCollisionEnter()
{
if (...)
{
var iceShards = CreateIceShards();
foreach (var iceShard in iceShards)
if (CreateNewMagic != null) //ALWAYS IS NULL
CreateNewMagic(iceShard);
}
}
}
public class IceShard : Magic
{
public override event MagicHandler CreateNewMagic;
}

Pass event through classes C#

I have a first class that raises an event when some changes occur:
public class MyFirstClass {
public event EventHandler ChangesHappened;
public MyFirstClass() {
}
public void MyMethod() {
//Thing happened
ChangesHappened?.Invoke(this, new EventArgs());
}
}
I also have a second class that have a list of FirstClass:
public class MySecondClass {
private List<MyFirstClass> first;
public MySecondClass() {
foreach(var f in first) {
first.Changed += (s, e) => {};
}
}
}
And last I have a WPF application with an instance of SecondClass. How can I handle the Changed event (FirstClass) from WPF? Should I create an event in SecondClass and raise it inside first.Changed += (s, e) => { NewEvent(this, new EventArgs()); } and then catch this in the WPF?
The objective is get the Changed event in the WPF application.
It seems to me that this is the simplest answer:
public class MySecondClass
{
public event EventHandler ChangesHappened;
private List<MyFirstClass> first;
public MySecondClass()
{
foreach (var f in first)
{
f.ChangesHappened += (s, e) => ChangesHappened?.Invoke(s, e);
}
}
}
Another option is to use Microsoft's Reactive Framework which lets you pass events (well observables) around as first-class language citizens.
You could do this:
void Main()
{
var msc = new MySecondClass();
msc.Changes.Subscribe(ep =>
{
/* Do stuff with
ep.Sender
ep.EventArgs
from the `MyFirstClass` instances
*/
});
}
public class MyFirstClass
{
public event EventHandler ChangesHappened;
public IObservable<EventPattern<EventArgs>> Changes;
public MyFirstClass()
{
this.Changes = Observable.FromEventPattern<EventHandler, EventArgs>(
h => this.ChangesHappened += h, h => this.ChangesHappened += h);
}
public void MyMethod()
{
ChangesHappened?.Invoke(this, new EventArgs());
}
}
public class MySecondClass
{
public IObservable<EventPattern<EventArgs>> Changes;
private List<MyFirstClass> first = new List<MyFirstClass>();
public MySecondClass()
{
this.Changes = first.Select(f => f.Changes).Merge();
}
}
As #Enigmativity already mentioned: When you have a class, that has to manage other classes (bunch of MyFirstClass references) then you have to forward your events from sub class to manager class.
public class MySecondClass
{
public event EventHandler Changed;
private List<MyFirstClass> firstClassList;
public MySecondClass()
{
firstClassList = new List<MyFirstClass>();
}
public void AddMyFirstClassList(List<MyFirstClass> firstClassList)
{
foreach (var firstClass in firstClassList)
AddMyFirstClass(firstClass);
}
public void AddMyFirstClass(MyFirstClass firstClass)
{
// from sub class to manager class
firstClass.Changed += firstClass_Changed;
firstClassList.Add(firstClass);
}
private void firstClass_Changed(object sender, EventArgs args)
{
Changed?.Invoke(sender, args);
}
public void RemoveMyFirstClass(MyFirstClass firstClass)
{
MyFirstClass.Remove -= firstClass_Changed;
firstClassList.Remove(firstClass);
}
}
Another option is to pass a callback function. You should avoid this, unless you need it explicity:
public class MyFirstClass
{
EventHandler handler;
public MyFirstClass(EventHandler handler)
{
this.handler = handler;
}
public void MyMethod()
{
handler?.Invoke(this, new EventArgs());
}
}
public class MySecondClass
{
private List<MyFirstClass> firstClassList;
public MySecondClass()
{
firstClassList = new List<MyFirstClass>();
}
// you have instantiated your class and passed your callback function previously.
public void AddMyFirstClass(MyFirstClass firstClass)
{
firstClassList.Add(firstClass);
}
// for demonstrating the instantiation.
public void AddMyFirstClass(EventHandler handler)
{
firstClassList.Add(new MyFirstClass(handler));
}
}

Why is a "forwarded" event not raised when assigning a method group but is when assigning a delegate?

Given the following code:
public delegate void Signal();
public static class SignalExtensions
{
public static void SafeInvoke(this Signal signal)
{
Signal copy = signal;
if (copy != null)
{
copy();
}
}
}
public class RootEventSource
{
public event Signal RootEvent;
public void Raise()
{
this.RootEvent.SafeInvoke();
}
}
public class EventForwarder
{
private readonly RootEventSource rootEventSource;
public EventForwarder(RootEventSource rootEventSource)
{
this.rootEventSource = rootEventSource;
// this is the critical part
this.rootEventSource.RootEvent
+= () => this.AnotherEvent.SafeInvoke();
}
public event Signal AnotherEvent;
// just an example of another method which is using the root event source
public override string ToString()
{
return this.rootEventSource.ToString();
}
}
class Program
{
static void Main(string[] args)
{
var rootEventSource = new RootEventSource();
var eventForwarder = new EventForwarder(rootEventSource);
eventForwarder.AnotherEvent += HandleAnotherEvent;
rootEventSource.Raise();
Console.WriteLine("done");
Console.ReadKey();
}
private static void HandleAnotherEvent()
{
Console.WriteLine("received AnotherEvent");
}
}
This results in the output:
received AnotherEvent
done
Now I make a slight change to the implementation of EventForwarder to use a method group for forwarding the event:
public EventForwarder(RootEventSource rootEventSource)
{
this.rootEventSource = rootEventSource;
this.rootEventSource.RootEvent += this.AnotherEvent.SafeInvoke;
}
The output becomes:
done
So AnotherEvent is not raised.
Until now i would have considered the two lines:
this.rootEventSource.RootEvent += this.AnotherEvent.SafeInvoke;
this.rootEventSource.RootEvent += () => this.AnotherEvent.SafeInvoke();
as being equivalent. It seems they're not.
So what is the difference? Plus why is the event not being raised?
PS: while usually R# suggests to replace () => this.AnotherEvent.SafeInvoke(); by this.AnotherEvent.SafeInvoke it doesn't do so here. So apparently it knows that it should not do it here.
When you assign a method group to event like this:
this.rootEventSource.RootEvent += this.AnotherEvent.SafeInvoke;
you in fact create a delegate from method SignalExtensions.SafeInvoke which as a parameter takes your this.AnotherEventdelegate object. Since it is initially null, you create a delegate with null parameter. This null value will of course never change, since delegates are immutable.
If you want to forward an event you should maybe do it like this:
public class EventForwarder
{
private readonly RootEventSource rootEventSource;
public EventForwarder(RootEventSource rootEventSource)
{
this.rootEventSource = rootEventSource;
}
public event Signal AnotherEvent
{
add { this.rootEventSource.RootEvent += value; }
remove { this.rootEventSource.RootEvent -= value; }
}
}

How to subscribe to an event with certain arguments c#?

I have an enumeration prior.
Each of my scripts has a property priority of prior type. (Every script has its own class)
I have a data provider, which can send events every frame.
I want a script to subscribe only to an event which has arguments with priority equal to the script's one.
For example, a script with moderate priority should receive only events with moderate parameter of event arguments
prior has too many members to create a special event argument class for each.
Unfortunately:
a)I know only how to subscribe to a certain event type.
b)I can't make a generic class for event arguments, because elements of enum are not types
How can I do it?
The project currently looks this way:
public class TDefault:MonoBehaviour,IDefault
{
public enum prior
{
none,
...,
terminal
};
prior priority;
public virtual void apply()//For override by scripts
{
}
void Start()
{
//There should be adding a method which calls apply() when event_manager
//sends Event with a certain priority
}
public TDefault ()
{
if(essential==null)
essential=new TEssential();
}
}
public class TApplyEventParam : EventArgs
{
public TDefault.prior priority;
public TApplyEventParam(TDefault.prior _priority)
{
priority=_priority;
}
}
public class event_manager : TDefault
{
//This has fixed type
event EventHandler<TApplyEventParam> handler=new EventHandler<TApplyEventParam>();
void Update ()
{
foreach (prior p in (prior[]) Enum.GetValues(typeof(prior)))
{
handler(this,new TApplyEventParam(p));
}
}
}
The problem you're dealing with, if I understood it correctly, is that you would like to have your event subscription conditionally called depending on the event payload (the priority value inside the TApplyEventParam). That is something that you cannot do which results in you having to filter out the unwanted events inside your event handler like proposed by #Henk-Holterman
Another approach could be to skip the usage of events and maintain your own list of subscribers inside the data provider.
Based on the terminology used by you in your question (not the code example) you could do something like this:
using System;
using System.Collections.Generic;
namespace Example
{
public enum Prior
{
None,
Moderate,
Terminal
};
public abstract class ScriptBase
{
public abstract Prior Prior { get; }
public abstract void Apply();
public void Start(DataProvider dataProvider)
{
dataProvider.Subscribe(Prior, Apply);
}
public void Stop(DataProvider dataProvider)
{
dataProvider.Unsubscribe(Prior, Apply);
}
}
public class ScriptHandlingModerateEvents : ScriptBase
{
public override Prior Prior
{
get { return Example.Prior.Moderate; }
}
public override void Apply()
{
Console.WriteLine("Handling moderate event by " + GetType().Name);
}
}
public class ScriptHandlingTerminalEvents : ScriptBase
{
public override Prior Prior
{
get { return Example.Prior.Terminal; }
}
public override void Apply()
{
Console.WriteLine("Handling terminal event by " + GetType().Name);
}
}
public class DataProvider
{
private readonly Dictionary<Prior, List<Action>> _subscribersByPrior;
public DataProvider()
{
_subscribersByPrior = new Dictionary<Prior, List<Action>>();
foreach (Prior prior in (Prior[])Enum.GetValues(typeof(Prior)))
{
_subscribersByPrior.Add(prior, new List<Action>());
}
}
public void Subscribe(Prior prior, Action action)
{
_subscribersByPrior[prior].Add(action);
}
public void Unsubscribe(Prior prior, Action action)
{
_subscribersByPrior[prior].Remove(action);
}
public void DoSomethingThatTriggersPriorEvents(int someValue)
{
Prior prior = someValue % 2 == 0 ? Prior.Moderate : Prior.Terminal;
foreach (var subscriber in _subscribersByPrior[prior])
{
subscriber();
}
}
}
public static class Program
{
public static void Main()
{
DataProvider dataProvider = new DataProvider();
var scriptHandlingModerateEvents = new ScriptHandlingModerateEvents();
scriptHandlingModerateEvents.Start(dataProvider);
var scriptHandlingTerminalEvents = new ScriptHandlingTerminalEvents();
scriptHandlingTerminalEvents.Start(dataProvider);
for (int i = 0; i < 10; i++)
{
dataProvider.DoSomethingThatTriggersPriorEvents(i);
}
scriptHandlingTerminalEvents.Stop(dataProvider);
scriptHandlingModerateEvents.Stop(dataProvider);
Console.WriteLine();
}
}
}
this way the DataProvider is not aware of scripts, but if that is not an issue, you could maintain a list of ScriptBase instances and check the Prior property inside the
DoSomethingThatTriggersPriorEvents like this:
public class DataProvider2
{
private readonly List<ScriptBase> _scripts = new List<ScriptBase>();
public void Subscribe(ScriptBase script)
{
_scripts.Add(script);
}
public void Unsubscribe(ScriptBase script)
{
_scripts.Remove(script);
}
public void DoSomethingThatTriggersPriorEvents(int someValue)
{
Prior prior = someValue % 2 == 0 ? Prior.Moderate : Prior.Terminal;
foreach (var script in _scripts)
{
if (script.Prior == prior)
{
script.Apply();
}
}
}
}

Super-simple example of C# observer/observable with delegates

I recently started digging into C# but I can't by my life figure out how delegates work when implementing the observer/observable pattern in the language.
Could someone give me a super-simple example of how it is done? I have googled this, but all of the examples I found were either too problem-specific or too "bloated".
The observer pattern is usually implemented with events.
Here's an example:
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();
}
}
See the linked article for a lot more detail.
Note that the above example uses C# 6 null-conditional operator to implement DoSomething safely to handle cases where SomethingHappened has not been subscribed to, and is therefore null. If you're using an older version of C#, you'd need code like this:
public void DoSomething()
{
var handler = SomethingHappened;
if (handler != null)
{
handler(this, EventArgs.Empty);
}
}
In this model, you have publishers who will do some logic and publish an "event."
Publishers will then send out their event only to subscribers who have subscribed to receive the specific event.
In C#, any object can publish a set of events to which other applications can subscribe.
When the publishing class raises an event, all the subscribed applications are notified.
The following figure shows this mechanism.
Simplest Example possible on Events and Delegates in C#:
code is self explanatory, Also I've added the comments to clear out the code.
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
}
}
Output:
Heard It by Listener
Heard It by Listener2
Heard It by Listener
Heard It by Listener2
Heard It by Listener
.
.
.
(infinite times)
Here's a simple example:
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;
}
}
Note:
This violates a rule in that I don't unhook the observer from the observable, this is perhaps good enough for this simple example, but make sure you don't keep observers hanging off of your events like that. A way to handle this would be to make ObserverClass IDisposable, and let the .Dispose method do the opposite of the code in the constructor
No error-checking performed, at least a null-check should be done in the constructor of the ObserverClass
I've tied together a couple of the great examples above (thank you as always to Mr. Skeet and Mr. Karlsen) to include a couple of different Observables and utilized an interface to keep track of them in the Observer and allowed the Observer to to "observe" any number of Observables via an internal list:
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);
}
}
}
Applying the Observer Pattern with delegates and events in c# is named "Event Pattern" according to MSDN which is a slight variation.
In this Article you will find well structured examples of how to apply the pattern in c# both the classic way and using delegates and events.
Exploring the Observer Design Pattern
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);
}
}
I did't want to change my source code to add additional observer , so I have written following simple example:
//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 :)
}
}
Something like this:
// 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)
{
}
}
.
observer pattern C# with event
.
link to the repository

Categories