Events and Delegates Vs Calling methods - c#

I hope this question is not to closely related to others but others don't seem to fill the gap in knowledge.
This seems to be hot topic to try and understand Events and Delegates and after reading many SO questions and MSDN articles I'm afraid to say I still don't understand. After some years creating great web applications, I found myself getting extremely frustrated in not understanding them. Please can anyone clarify this in common code. So the question is, why would you use events and delegates over calling a method?
Below is some basic code I written at work. Would I be able to leverage events and delegates?
Public Class Email
{
public string To {get;set;}
//Omitted code
public void Send()
{
//Omitted code that sends.
}
}
Public Class SomeClass
{
//Some props
Public void DoWork()
{
//Code that does some magic
//Now Send Email
Email newEmail = new Email();
newEmail.To = "me#me.com";
newEmail.Send();
}
}
This is probably not the best example but is there anyway that the DoWork() method can subscribe to the Email? Would this work? Any help for me to truly understand events and delegates would be greatly appreciated.
Regards,

The biggest reason I have found in real-world programming for the use of events and delegates is easing the task of code maintenance and encouraging code reuse.
When one class calls methods in another class, those classes are "tightly coupled". The more classes you have tightly coupled, the more difficult it becomes to make a change to one of them without having to also change several others. You may as well have written one big class at that point.
Using events instead makes things more "loosely coupled" and makes it much easier to change one class without having to disturb others.
Taking your example above, suppose we had a third class, Logger, that should log when an email is sent. It uses a method, LogEvent(string desc, DateTime time), to write an entry to the log:
public class Logger
{
...
public void LogEvent(string desc, DateTime time)
{
...//some sort of logging happens here
}
}
If we use methods, we need to update your Email class' Send method to instantiate a Logger and call its LogEvent method:
public void Send()
{
//Omitted code that sends.
var logger = new Logger();
logger.LogEvent("Sent message", DateTime.Now);
}
Now Email is tightly coupled to Logger. If we change the signature of that LogEvent method in Logger, we will also have to make changes to Email. Do you see how this can quickly become a nightmare when you are dealing with even a medium-sized project? Furthermore, no one wants to even try to use the LogEvent method because they know that if they need to make any sort of change to it, they will have to start changing other classes, and what should have been an afternoon's worth of work quickly turns into a week. So instead, they write a new method, or a new class, that then becomes tightly coupled to whatever else they are doing, things get bloated, and each programmer starts to get into their own little "ghetto" of their own code. This is very, very bad when you have to come in later and figure out what the hell the program is doing or hunt down a bug.
If you put some events on your Email class instead, you can loosely couple these classes:
Public Class Email
{
public event EventHandler<EventArgs> Sent;
private void OnSent(EventArgs e)
{
if (Sent!= null)
Sent(this, e);
}
public string To {get;set;}
//Omitted code
public void Send()
{
//Omitted code that sends.
OnSent(new EventArgs());//raise the event
}
}
Now you can add an event handler to Logger and subcribe it to the Email.Sent event from just about anywhere in your application and have it do what it needs to do:
public class Logger
{
...
public void Email_OnSent(object sender, EventArgs e)
{
LogEvent("Message Sent", DateTime.Now);
}
public void LogEvent(string desc, DateTime time)
{
...//some sort of logging happens here
}
}
and elsewhere:
var logger = new Logger();
var email = new Email();
email.Sent += logger.Email_OnSent;//subscribe to the event
Now your classes are very loosely coupled, and six months down the road, when you decide that you want your Logger to capture more or different information, or even do something totally different when an email is sent, you can change the LogEvent method or the event handler without having to touch the Email class. Furthermore, other classes can also subscribe to the event without having to alter the Email class, and you can have a whole host of things happen when an email is sent.
Now maintaining your code is much easier, and other people are much more likely to reuse your code, because they know they won't have to go digging through the guts of 20 different classes just to make a change to how something is handled.
BIG EDIT: More about delegates. If you read through here: Curiosity is Bliss: C# Events vs Delegates (I'll keep links to a minimum, I promise), you see how the author gets into the fact that events are basically special types of delegates. They expect a certain method signature (i.e. (object sender, EventArgs e)), and can have more than one method added to them (+=) to be executed when the method is raised. There are other differences as well, but these are the main ones you will notice. So what good is a delegate?
Imagine you wanted to give the client of your Email class some options for how to send the mail. You could define a series of methods for this:
Public Class Email
{
public string To {get;set;}
//Omitted code
public void Send(MailMethod method)
{
switch(method)
{
case MailMethod.Imap:
ViaImap();
break;
case MailMethod.Pop:
ViaPop();
break;
}
}
private void ViaImap() {...}
private void ViaPop() {...}
}
This works well, but if you want to add more options later, you have to edit your class (as well as the MailMethod enum that is assumed here). If you declare a delegate instead, you can defer this sort of decision to the client and make your class much more flexible:
Public Class Email
{
public Email()
{
Method = ViaPop;//declare the default method on instantiation
}
//define the delegate
public delegate void SendMailMethod(string title, string message);
//declare a variable of type SendMailMethod
public SendMailMethod Method;
public string To {get;set;}
//Omitted code
public void Send()
{
//assume title and message strings have been determined already
Method(title, message);
}
public void SetToPop()
{
this.Method = ViaPop;
}
public void SetToImap()
{
this.Method = ViaImap;
}
//You can write some default methods that you forsee being needed
private void ViaImap(string title, string message) {...}
private void ViaPop(string title, string message) {...}
}
Now a client can use your class with its own methods or provide their own method to send mail just about however they choose:
var regularEmail = new Email();
regularEmail.SetToImap();
regularEmail.Send();
var reallySlowEmail = new Email();
reallySlowEmail.Method = ViaSnailMail;
public void ViaSnailMail(string title, string message) {...}
Now your classes are somewhat less tightly coupled and much easier to maintain (and write tests for!). There are certainly other ways to use delegates, and lambdas sort of take things up a notch, but this should suffice for a bare-bones introduction.

Ok, I understand this answer wont strictly speaking be correct, but I'll tell you how I came to understand them.
All functions have a memory address, and some functions are simple get/set for data. It helps to think of all variables as being functions with only two methods - get and set. You're quite comfortable passing variables by reference, which means (simplistically) you are passing a pointer to their memory, which enables some other code to call their get/set methods, implicitly by using "=" and "==".
Now translate that concept to functions and code. Some code and functions have names (like variable names) which you give them. you are used to executing those functions by calling their name; but the name is just a synonym for their memory location (simplistically). By calling the function you are de-referencing its memory address using its name, and then calling the method which lives at that memory address.
As I said, this is all very simplistic and in various ways, incorrect. But it helps me.
So - is it possible to pass the memory address of a function but not call it ? In the same way you pass a reference to a variable without evaluating it ? I.e. what is the equivalent of calling
DoSomeFunction(ref variablePointer)
Well, the reference to a function is called a delegate. But because a function can also take parameters (which a variable cannot) you need to use a calling syntax more elaborate than just ref. You set up the call you want to make into a delegate structure and pass that delegate stucture to the recipient, who can either immediately evaluate (call) that delegate, or store it for later use.
Its the "store for later use" that is the key to understanding event handlers. The special (and somewhat confusing) syntax around event handlers is just another way of setting up a function pointer (delegate) and add it to a list of function pointers that the recipient class can evaluate at some convenient time.
A simple way of looking at event handlers would be;
class myClass
{
public List<delegate> eventHandlers = new List<delegate>();
public void someMethod()
{
//... do some work
//... then call the events
foreach(delegate d in eventHandlers)
{
// we have no idea what the method name is that the delegate
// points to, but we dont need to know - the pointer to the
// function is stored as a delegate, so we just execute the
// delegate, which is a synonym for the function.
d();
}
}
}
public class Program()
{
public static void Main()
{
myClass class1 = new myClass();
// 'longhand' version of setting up a delegate callback
class1.eventHandlers.Add(new delegate(eventHandlerFunction));
// This call will cause the eventHandlerFunction below to be
// called
class1.someMethod();
// 'shorthand' way of setting up a delegate callback
class1.eventHandlers.Add(() => eventHandlerFunction());
}
public static eventHandlerFunction()
{
Console.WriteLine("I have been called");
}
It gets slightly more complicated when you want the caller of the delegate to pass in some values to the function, but otherwise all delegate concepts are the same as the concepts of "ref" variables - they are references to code which will be executed at a later date, and typically you pass them as callbacks to other classes, who will decide when and whether to execute them. In earler languages delegates were pretty much the same as "function pointers" or (in beloved long departed Nantucket Clipper) "Code blocks". Its all much more complex than simply passing around a memory address of a block of code, but if you hang on to that concept, you wont go far wrong.
Hope that helps.

The simplest way of thinking about the use of delegates is to think in terms of when you want to call a method, but you don't not yet know which one (or ones).
Take a control's Click event handler, for example. It uses the EventHandler delegate. The signature is void EventHandler(object sender, EventArgs e);. What this delegate is there for is that when someone clicks the control I want to be able to call zero or more methods that have the EventHandler signature, but I don't know what they are yet. This delegate lets me effectively call unknown future methods.
Another example is LINQ's .Select(...) operator. It has the signature IEnumerable<TResult> Select<TSource, TResult>(this IEnumerable<TSource> source, Func<TSource, TResult> selector). This method contains a delegate Func<TSource, TResult> selector. What this method does is takes a sequence of values from source and applies an as yet unknown projection to produce a sequence of TResult.
Finally, another good example is Lazy<T>. This object has a constructor with this signature: public Lazy(Func<T> valueFactory). The job of Lazy<T> is to delay the instantiate of T until the first time it is used, but then to retain that value for all future uses. It presumably is a costly instantiation that would be ideal to avoid if we don't need the object, but if we need it more than one we don't want to be hit with the cost. Lazy<T> handles all the thread locking, etc, to make sure that only one instance of T is created. But the value of T returned by Func<T> valueFactory can be anything - the creators of Lazy<T> has no idea what the delegate will be, and nor should they.
This, to me, is the most fudamentally important thing to understand about delegates.

why would you use events and delegates over calling a method?
In the context of the example you posted, if you wanted to send emails asynchronously, you would have to implement a notification mechanism.
See the SmtpClient implementation for an example: https://msdn.microsoft.com/en-us/library/system.net.mail.smtpclient.sendcompleted%28v=vs.110%29.aspx

If more of an explanation is required, rather than code examples, I'll try to explain why you would use a Delegate or Event in the example you gave above.
Imagine that you wish to know if the email was sent or not after you called Email.Send().
In the Email Class you would have two events - one for a failed send, and one for a successful send.
When the Email Class sends without an error, it would look to see if there are any subscribers to the 'SuccessfulSend()' event, and if there are, it raises that event. This would then notify the subscribers that wanted to be informed if the send was successful so that they can perform some other task.
So you could have an event handler that is notified of the successful send, and in this handler, you could call another method (DoMoreWork()).
If the Email.Send() failed, you could be notified of this, and call another method that logs the failure for later reference.
With regards to Delegates, if there were three different Email Classes that used different functionality (or servers) to send mail, the client calling the Email.Send() method, could supply the relevant Email Class to use when sending the email.
The Email Class would use the IEmail interface, and the three Email Classes would implement IEmail (To, From, Subject, Body, Attachments, HTMLBody etc.), but could perform the interactions/rules in different ways.
One could require a Subject, another require an Attachment, one could use CDONTS, another use a different protocol.
The client could determine if it needs to use CDONTS depending on where it is installed, or it could be in an area of the app where an attachment is required, or would format the body in HTML.
What this does is to remove the burden of logic from the client and all of the places where these checks and logic should be checked, and move it into the single versions of the relevant Class.
Then the client simply calls the Email.Send() after providing the correct object to use in its constructor (or by using a settable property).
If a fix or change to a particular email object's code is required - it is carried out in one place rather than finding all areas in the client and updating there.
Imagine if your Email Class was used by several different applications...

Related

I am new to delegates and wonder how to break down the following code

I have the following code and am wondering how to break it down? It works great but was written by a guru and is over my head. Thank you in advance for any help.
The code basically writes device information sent and received to the GUI. It seems like it has events created based on the device and also invokes GUI stuff.
Why would you need to invoke?
I guess I'm wondering if this is overly complicated or appropriate? What may be a better way to accomplish the same task?
I'm also wondering what the "delegate { };" does?
public event EventHandler CommunicationPerformed = delegate { };
SerialPort _port;
readonly int _delay = 100;
private string ReadAndUpdateStatus()
{
string read = _port.ReadExisting();
CommunicationPerformed?.Invoke(this, new LoaderReadWriteEventArgs(read, LoaderCommunicationDirection.Read));
return read;
}
private void WriteAndUpdateStatus(string data)
{
if (!data.StartsWith("//")) //ignore "Comment" lines but show them on the GUI to read
_port.Write(data);
CommunicationPerformed?.Invoke(this, new LoaderReadWriteEventArgs(data, LoaderCommunicationDirection.Write));
}
public class LoaderReadWriteEventArgs : EventArgs
{
public LoaderCommunicationDirection Direction { get; }
public string Value { get; }
public LoaderReadWriteEventArgs(string value, LoaderCommunicationDirection direction)
{
Value = value;
Direction = direction;
}
}
public enum LoaderCommunicationDirection
{
Read,
Write
}
You asked three questions, and as usual, only one of them got answered. Try to ask only one question in your question.
I'm also wondering what the delegate { } does?
public event EventHandler CommunicationPerformed = delegate { };
As the other answer notes, events are null by default in C#. This technique makes an event handler that does nothing, but is not null.
There are, unfortunately, many syntaxes for an anonymous function in C#. delegate {} means "give me a do-nothing function that matches any non-ref-out formal parameter list that is void returning". That's why people do delegate{}, because it works almost anywhere in a context where an event handler is expected.
I think you need to review this https://learn.microsoft.com/en-us/dotnet/standard/events/.
Why would you need to invoke?
To broadcast to event handlers (any party who registered for this event get notified this way)
I guess I'm wondering if this is overly complicated or appropriate?
*What may be a better way to accomplish the same task?
This is not complicated. This is pretty much as easy as it gets.*
I'm also wondering what the "delegate { };" does?
my two cents.
I dont know which code line you are refering but a delegate is a type that holds a reference to a method. A delegate is declared with a signature that shows the return type and parameters for the methods it references, and can hold references only to methods that match its signature. A delegate is thus equivalent to a type-safe function pointer or a callback. A delegate declaration is sufficient to define a delegate class.
orhtej2 answered your first question quite nicely. Using the explicit Invoke method allows you to leverage the null conditional operator, which reduces the code to fire the event a single line.
As for whether this is overly complicated: No, that's basically how events are done.
What I've sometimes seen (especially in combination with the INotifyPropertyChanged interface in MVVM patterns) are helper methods, which encapsulate the longer, but more obvious pre-C#6 code and let you fire the event with less plumbing.
private void FireCommPerformed(string value, LoaderCommunicationDirection direction)
{
EventHandler handler = CommunicationPerformed;
if (handler != null)
{
handler(this, new LoaderReadWriteEventArgs(value, direction)));
}
}
You could then use it like this:
private string ReadAndUpdateStatus()
{
string read = _port.ReadExisting();
FireCommPerformed(read, LoaderCommunicationDirection.Read);
return read;
}
The Delegate { } is simply an empty delegate, like a null for events. Unless some other method in the code subscribes to the CommunicationPerformed event of this class during runtime, nothing will happen when the event is fired.
Let's focus in on what is exactly happening here. This should help you figure out everything else.
CommunicationPerformed?.Invoke(this, new LoaderReadWriteEventArgs(read, LoaderCommunicationDirection.Read));
This is checking to see if the delegate (event handlers are delegates) (CommunicationPerformed) is null.
Delegates are pointers (but with extra functionality).
If the delegate (pointer) is null, it means that nothing has been assigned to it.
Pointers store memory locations. In this case, it makes a memory reference to the function 'this'. 'This' is a reference to ReadAndUpdateStatus().
So this line basically says: "since the pointer is null, have this pointer reference the ReadAndUpdateStatus() function".
But what about the event args? Well... This is where delegates diverge from pointers.
Delegates don't just safely hold and store memory locations. They also can hold parameters.
You use a class that extends from EventArgs as the way of passing in a list of parameters.
From here, the event handler (event handlers are delegates) CommunicationPerformed will coordinate sending that list of arguments to whatever functions require it.
These functions are called whenever CommunicationPerformed is invoked (e.g. told to run). This is typically indicated with a:
+=CommunicationPerformed(foo,bar)
Now - why would use event handlers (or any delegate - for that matter)?
They're verbose and annoying to read (way more work than writing a simple bool and a trigger function), they don't look like other function, and they're frankly weird - right?
Except that they're really useful. Here's how:
1.) They work a lot like Tasks. You can invoke them in Parallel, in loops, wherever. They keep consistent state. They don't "bleed" and cause bugs.
2.) They're pointers. Guaranteed pass-by-reference. Except, they're magical, and if you stop using the delegate, they won't linger in memory.
3.) They allow you to control state in loops. Sometimes, a bool trigger won't work properly if you're in a really tight loop. You fire an event? Guaranteed behavior that your trigger will only be fired once.
I'm gonna try to answer #1 and #2 (3 is already covered).
#1 - At some point, someone decided that other parts of the program could subscribe to an event that tells them when communication has been performed. Once that decision has been made, it's kind of a "contract". You perform the communication->you fire the event that notifies subscribers that communication has been performed. What those subscribers are doing about that, or why they need to know...Actually not really any of your concern if this class is your focus. In theory, at least. And often that's really practically the case. If your class is doing its job, it's not really your concern who is listening to the events.
#2 - I do think the method of declaring events and event handlers in your code is overly complicated. Plenty of people (and official Microsoft best practices) disagree with me. You can google "why should my event handlers use eventargs" and read plenty on the subject. Or Look here. Another approach is the following:
public event Action<string, LoaderCommunicationDirection> CommunicationPerformed;
void PerformWrite()
{
string myComm = "String I'm sending";
//Line of code that performs communication that writes string here
CommunicationPerformed?.Invoke(myComm, LoaderCommunicationDirection.Write);
}
This is much more succinct than having an entire class that derives from EventArgs. However, it has the very obvious drawback that if you are an event subscriber...you have no idea what string is. Of course, since it's named value in your code...that's not much more helpful. And a comment above the event declaration is just about as useful.

How to secure delegate instance reference

In the perspective of callbacks, I am facing a strange situation when I knew that myDelegate.Target contains the reference to the class whose method it contains. (I searched it on SO, however I excuse if I missed some thread already answering this)
For example
public delegate void TravePlanDelegate();
public class Traveller
{
//Papa is planing a tour, along with Mama
public void Planner()
{
//Asking me (delegate) to hold a letter about PlanA's detail
TravelPlanDelegate myPlan = PlanA;
//Sending me to TravelAgency office with letter
new TravelAgency().ExecuteTravelPlan(myPlan);
}
public void PlanA()
{
//Papa's open plan with Mama
Console.WriteLine("First Berline, then New Yark and finally Lahore");
}
public void PlanB()
{
//Papa's secret plan
Console.WriteLine("First Dubai, and then Lahore");
}
}
public class TravelAgency
{
public void ExecuteTravelPlan(TravePlanDelegate tp)
{
Traveller traveller = (Traveller)tp.Target;
//Here it should execute plan
//tp.Target - A reference to Traveler class, which can lead travel
//agency to Papa's secret plan (And exposes it to Mama)
}
}
In this example, TravelAgency can get information from delegate about papa's secret plan too. Did I get delegate concept properly or missing something?
Your assumption is correct. Unfortunately, however you try to "encapsulate" your object- there must always be a reference to it somewhere, otherwise it would be impossible to invoke it's instance method.
As some kind of counter measure, you can proxy the method invocation to a lambda expression:
TravelPlanDelegate myPlan = (args) =>PlanA(args);
This makes it less likely that any rogue code will attempt to carry out some ill intended operations on your code, since knowing how your code looks like in advance will not help it accomplish a thing.
Note that this does not ensure a thing, since the produced delegate still has a Target property to an object which holds a reference to yours.
Crackers which are smart enough can still apply reflection to the generated class and obtain a reference to your object.
Conclusion:
Only consume code you trust - it is not much of a problem in today's Open Source driven world.

consuming stored events via several consumers and event handlers

I am currently using this pattern to deal with events coming from some event sink (e.g. enterprise service bus, queue, EventStore). The idea is to instantiate several IEventWorkers (see concrete example below) in a list and passing events on, for example, by invoking the HandleEvent methods of each instance whilst looping over the list. This is the basic code of an IEventWorkers concrete:
public class EventWorker : IEventWorker
{
private Dictionary<Type, Action<object>> CreateEventHandlerMapping()
{
return new Dictionary<Type, Action<object>>
{
{typeof (Event1), o => Handle(o as Event1)},
{typeof (Event2), o => Handle(o as Event2)},
};
}
private void Handle(Event1 eventToHandle)
{
}
private void Handle(Event2 eventToHandle)
{
}
public void HandleEvent(IEvent evt)
{
var eventType = evt.GetType();
if (_eventHandlerMapping.ContainsKey(eventType))
{
_eventHandlerMapping[eventType](evt);
}
}
}
Maybe there is a better way to do this?
PS:
This comes quite close to what I am trying to achieve. I do not fully understand how the ObserverRegistry would work to distribute all events coming from, for example, an event queue.
Your question is quite broad in nature; perhaps a little too much. I encourage you to refine it.
However, you ask for potential improvements, and I can think of at least one thing specific enough:
You may use double-dispatch instead of type-casting for type-safety.
See the visitor pattern for more information. In your case, you would create an Accept-like method on IEvent and call it in HandleEvent:
public void HandleEvent(IEvent evt)
{
evt.Accept(this);
}
Accept methods on event types would look like:
public void Accept(IEventWorker worker)
{
worker.Handle(this);
}
(While this is still a virtual call of course, notice the handler method overload is now selected statically. This is in contrast to your existing runtime dictionary lookup.)
The IEventWorker interface would mandate a method per event type, which is the equivalent of "registering" them, although this time in a type-safe manner. Note that this would change their access level on your implementation, which is fine.
You can then remove the mapping dictionary entirely; you're now using the virtual table of the class to the same effect.
I wouldn't jump on also claiming performance improvements (if it even mattered in your scenario), but if it is important you may want to test and see (you should at least expect better performance).

Is it possible to use Delegates to allow a calling process to provide an external function to run?

I have created a class that handles encrypted database traffic. I have used external Event definitions successfully, allowing the calling process to properly handle errors that - while they occurred within the database module - actually originated from the calling procedure.
Using the external Error handler I would do the following:
public event EventHandler ErrorStatusChanged;
...and later, if/when such occurred, I would handle it like this:
if (ErrorStatusChanged != null)
{
ErrorStatusChanged(this, EventArgs.Empty);
}
...and that seems to work just fine. However, now I want to extend further using a callback function, but I have only a few clues how I might approach this situation. (I feel sure that it is possible to accomplish this, but I'm fairly lost/confused as to actual implementation...)
Something like:
public delegate void Update_System_Status (bool dbConnected, string textStatus);
...and then later (I'm sure I've got this wrong, the compiler flags it even before compile time):
if (Update_System_Status != null)
{
Update_System_Status(bConnFlag, sConnTextStatus);
}
I'd like to build a couple of callbacks - one that allows the datahandler class to inform the calling process that it has successfully connected (or not), and another to handle updating a progress bar during the longer mass-update processes. And after numerous searches using [callback] and/or [delegate] as keywords, I'm getting nowhere quickly. I am, however, getting really confused!
I had envisioned that I would provide some sort of interface, very similar to the EventHander (above) and be able to determine - later on, when it is needed - whether the calling procedure provided the proper function, and call it if/when possible. I know that not all programmers will want to provide a main form update callback function to this database handler, so I figure I'll need to somehow "know" when one has been provided, and when not.
I have unsuccessfully employed the [delegate] keyword, and have no idea how to use the [interface] directive at all - all of the examples I keep running into illustrate the functions being internal to the class, which is exactly not what I am trying to achieve. I am trying to provide a framework that will allow an external process to provide a function that, when something happens inside the class/object that would be good to update the external (calling) system, could do so by calling the provided function (from outside).
Thanks (in advance) for your assistance - I'm lost!
I think you problem is that you are only declaring a delegate type - you are not declaring a property of that type
Try something like this:
public delegate void MyDelegateType(bool dbConnected, string textStatus);
public MyDelegateType Update_System_Status { get; set; }
then you should be able to use it like you want:
if (Update_System_Status != null)
{
Update_System_Status(bConnFlag, sConnTextStatus);
}
but if you are going to use it like this you might aswell make it an event:
public event MyDelegateType MyEvent;
You declared delegate correctly. What you are missing is a member of this class what will use that delegate declaration. The code you tries is valid for events (which are multicast delagates), though you omit event definition itself (therefore you code doesn't work). Callbacks are usually passed via method calls (but you can as well pass it via property):
public void DoSomething(Update_System_Status callback)
{
// call callback
callback?.Invoke(false, "some status");
}
or
public Update_System_Status Callback {get; set;}
// and then somewhere (using pre C# 6.0 syntax)
var callback = Callback;
if(callback != null)
callback(true, "some status");
If you don't need proper parameter names (in your case they have different type, so impossible to make mistake which is which), then you can simply use Action<> without need to declare delegate before:
public void DoSomething(Action<bool, string> callback) { ... }

How you would you describe the Observer pattern in beginner language?

Currently, my level of understanding is below all the coding examples on the web about the Observer Pattern. I understand it simply as being almost a subscription that updates all other events when a change is made that the delegate registers. However, I'm very unstable in my true comprehension of the benefits and uses. I've done some googling, but most are above my level of understanding.
I'm trying to implement this pattern with my current homework assignment, and to truly make sense on my project need a better understanding of the pattern itself and perhaps an example to see what its use. I don't want to force this pattern into something just to submit, I need to understand the purpose and develop my methods accordingly so that it actually serves a good purpose. My text doesn't really go into it, just mentions it in one sentence. MSDN was hard for me to understand, as I'm a beginner on this, and it seems more of an advanced topic.
How would you describe this Observer pattern and its uses in C# to a beginner?
For an example, please keep code very simple so I can understand the purpose more than complex code snippets. I'm trying to use it effectively with some simple textbox string manipulations and using delegates for my assignment, so a pointer would help!
The best example I can come up with is that of a mailing list (as an example).
You, the observer, subscribe to a mailing list and you observe the list. When you are no longer interested in the list, you unsubscribe.
This concept is the observer pattern. Two or more classes are involved. One or more class, subscribes to a publisher class (there are different names) and then the first class (and every subscribing class) will get notified when ever the publisher desires.
This is how I explained it to my wife, who often listens to my rantings about programming and design theory. It made sense to her. I realize this might be too simple for you but is a good start...
Regards,
Frank
Check out "Head First: Design Patterns" for some really, smack-your-forehead easy to follow descriptions of the major patterns.
For Observer it is important to understand that it describes a one-to-many relationship and uses a subscription model for telling other classes when there has been a change. RSS, Atom, and Twitter work along these lines.
The Observer wants to know when anything changes, so it subscribes to the Subject. The Subject does not know the Observer. This is the important part. The Subject just defines the Interface (or delegate) the Observer needs to provide, and allows the registration.
In short: The Observer pattern allows your observer to be called from a subject, that does not care who the observer is and if it even exists.
There are two objects NOTIFIER and OBSERVER. NOTIFIER knows nothing about OBSERVER, while OBSERVER knows that NOTIFER implements a event.
OBSERVER uses the event to inform other objects that something happened. Simply spoken an event is a list of methods. Because OBSERVER wants to be notified if something happend, OBSERVER adds a method, that should be called if something happens, to the event of NOTIFER.
So if the thing happens, that NOTIFIER publishes with this event, NOTIFIER just walks over the list of methods and calls them. When the method added by OBSERVER is called, OBSERVER knows that the thing happend and can do what ever is required in this case.
Here is a example notifier class with a ValueChanged() event.
// Declare how a method must look in order to be used as an event handler.
public delegate void ValueChangedHandler(Notifier sender, Int32 oldValue, Int32 newValue);
public class Notifier
{
// Constructor with an instance name.
public Notifier(String name)
{
this.Name = name;
}
public String Name { get; private set; }
// The event that is raised when ChangeValue() changes the
// private field value.
public event ValueChangedHandler ValueChanged;
// A method that modifies the private field value and
// notifies observers by raising the ValueChanged event.
public void ChangeValue(Int32 newValue)
{
// Check if value really changes.
if (this.value != newValue)
{
// Safe the old value.
Int32 oldValue = this.value;
// Change the value.
this.value = newValue;
// Raise the ValueChanged event.
this.OnValueChanged(oldValue, newValue);
}
}
private Int32 value = 0;
// Raises the ValueChanged event.
private void OnValueChanged(Int32 oldValue, Int32 newValue)
{
// Copy the event handlers - this is for thread safty to
// avoid that somebody changes the handler to null after
// we checked that it is not null but before we called
// the handler.
ValueChangedHandler valueChangedHandler = this.ValueChanged;
// Check if we must notify anybody.
if (valueChangedHandler != null)
{
// Call all methods added to this event.
valueChangedHandler(this, oldValue, newValue);
}
}
}
Here a example observer class.
public class Observer
{
// Constructor with an instance name.
public Observer(String name)
{
this.Name = name;
}
public String Name { get; private set; }
// The method to be registered as event handler.
public void NotifierValueChanged(Notifier sender, Int32 oldValue, Int32 newValue)
{
Console.WriteLine(String.Format("{0}: The value of {1} changed from {2} to {3}.", this.Name, sender.Name, oldValue, newValue));
}
}
A small test application.
class Program
{
static void Main(string[] args)
{
// Create two notifiers - Notifier A and Notifier B.
Notifier notifierA = new Notifier("Notifier A");
Notifier notifierB = new Notifier("Notifier B");
// Create two observers - Observer X and Observer Y.
Observer observerX = new Observer("Observer X");
Observer observerY = new Observer("Observer Y");
// Observer X subscribes the ValueChanged() event of Notifier A.
notifierA.ValueChanged += observerX.NotifierValueChanged;
// Observer Y subscribes the ValueChanged() event of Notifier A and B.
notifierA.ValueChanged += observerY.NotifierValueChanged;
notifierB.ValueChanged += observerY.NotifierValueChanged;
// Change the value of Notifier A - this will notify Observer X and Y.
notifierA.ChangeValue(123);
// Change the value of Notifier B - this will only notify Observer Y.
notifierB.ChangeValue(999);
// This will not notify anybody because the value is already 123.
notifierA.ChangeValue(123);
// This will not notify Observer X and Y again.
notifierA.ChangeValue(1);
}
}
The output will be the following.
Observer X: The value of Notifier A changed from 0 to 123.
Observer Y: The value of Notifier A changed from 0 to 123.
Observer Y: The value of Notifier B changed from 0 to 999.
Observer X: The value of Notifier A changed from 123 to 1.
Observer Y: The value of Notifier A changed from 123 to 1.
To understand delegate types I am going to compare them with class types.
public class Example
{
public void DoSomething(String text)
{
Console.WriteLine(
"Doing something with '" + text + "'.");
}
public void DoSomethingElse(Int32 number)
{
Console.WriteLine(
"Doing something with '" + number.ToString() + "'.");
}
}
We defined a simple class Example with two methods. Now we can use this class type.
Example example = new Example();
While this works the following does not work because the types do not match. You get a compiler error.
Example example = new List<String>();
And we can use the variable example.
example.DoSomething("some text");
Now the same with a delegate type. First we define a delegate type - this is just a type definition like the class definition before.
public delegate void MyDelegate(String text);
Now we can use the delegate type, but we cannot store normal data in a delegate type variable, but a method.
MyDelegate method = example.DoSomething;
We have now stored the method DoSomething() of the object example. The following does not work because we defined MyDelegate as a delegate taking one string parameter and returning void. DoSomethingElse returns void but takes an integer parameter so you get a compiler error.
MyDelegate method = example.DoSomethingElse;
And finally you can use the variable method. You cannot perform data manipulation because the variable stores no data but a method. But you can call the method stored in the variable.
method("Doing stuff with delegates.");
This calls the method we stored in the variable - example.DoSomething().
The observer pattern is just like it sounds -
It's a means for some objects to watch an object, observing it for changes.
In C#, this becomes somewhat simple, since events are basically a language-specific means of implementing the observer pattern. If you've ever used events, you've used the observer pattern.
In other languages, this isn't built in, so there have been many attempts to formalize approaches to handling this.
Observer is like a direct line of communication. Rather than have all your relatives call you to find out how you are, when you get sick write a card and everyone who is interested gets it (or a copy). When you get better, you send out a card. When you stub your toe, you send out a card. When you get an A, you send out a card.
Anyone who cares gets on your mass mailing list and can respond however they see fit.
This dependency is great for UI. If I have a process that is slow (for example), it can fire an even when progress is made. A progress bar element could observe that and update its coverage. An OK button could observe that and become active at 100%. A cursor could observe that an animate until the progress is 100%. None of these observers needs to know about each other. Furthermore, none of these elements strictly needs to know what is driving them either.
This pattern is probably one of the most basic, if not the most basic pattern there is.
There are two "people" involved; the publisher and the subscriber/observer.
An observer simply asks the publisher to notify him when there is "news". News can be anything of importance here. It can be the temperature of the air, it can be a new post on a website, it can be the time of day.
Probably the thing you are having trouble with is defining the proper interfaces. The interface defines the interaction between the Subscriber and the Publisher.
First make a C# WinForms application
Setup Program.cs like this
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
}
interface IObserver
{
void Refresh(List<string> DisplayList);
}
class ObserverList : List<IObserver>
{
public void Refresh(List<String> DisplayList)
{
foreach (IObserver tItem in this)
{
tItem.Refresh(DisplayList);
}
}
}
}
We are making two things here. The first the interface which the subscribers will implement. Then a list for the publisher to hold all the subscribers.
Then make form one with two buttons, one labeled Form 2 and the other Labeled Form 3. Then add a textbox, then another button labeled Add
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
private List<string> DataList= new List<string>();
private ObserverList MyObservers = new ObserverList();
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
Form2 frmNewForm = new Form2();
MyObservers.Add(frmNewForm);
frmNewForm.Show();
MyObservers.Refresh(DataList);
}
private void button2_Click(object sender, EventArgs e)
{
Form3 frmNewForm = new Form3();
MyObservers.Add(frmNewForm);
frmNewForm.Show();
MyObservers.Refresh(DataList);
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void button3_Click(object sender, EventArgs e)
{
DataList.Add(textBox1.Text);
MyObservers.Refresh(DataList);
textBox1.Text = "";
}
}
}
I deliberately set up the Form2 button and the FOrm3 button to make multiple copies of each type of Form. For example, you can have twelve up at once.
You will notice that after creating each form I put it into the Observers list. I am able to do this because both Form2 and Form3 implement IObserver. After I show the Form I call refresh on the Observer list so the new form is updated with the latest data. Note I could have cast it to a variable of IObserver and updated just that form. I am trying to be as brief as possible.
Then for the Add button 'Button3' I pull the text from the textbox store it in my DataList and then refresh all the observers.
Then make Form2. Add a list box and the following code.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
public partial class Form2 : Form,IObserver
{
public Form2()
{
InitializeComponent();
}
private void Form2_Load(object sender, EventArgs e)
{
}
void IObserver.Refresh(List<string> DisplayList)
{
this.listBox1.Items.Clear();
foreach (string s in DisplayList)
{
this.listBox1.Items.Add(s);
}
this.listBox1.Refresh();
}
}
}
Then Add Form3, a combobox and add the following code.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
public partial class Form3 : Form,IObserver
{
public Form3()
{
InitializeComponent();
}
private void Form3_Load(object sender, EventArgs e)
{
}
void IObserver.Refresh(List<string> DisplayList)
{
this.comboBox1.Items.Clear();
foreach (string s in DisplayList)
{
this.comboBox1.Items.Add(s);
}
this.comboBox1.Refresh();
}
}
}
You will notice that each form implements the refresh method of the IObserver interface slightly different. One is for a listbox the other for a combo box. The use of interfaces is the key element here.
IN a real world application this example would be more complex. For example instead of passing the string list in the Refresh Interface. It would not have any parameters. Instead the Publisher (Form1 in this example) would implement a publisher interface and register itself with the Observers as they are being initialized. Each observer would be able to accept a publisher in it's initialization routine. Then when it is refreshed it would pull the string list out of the Publisher via a method exposed through the interface.
For more complex applications with multiple types of data this allows you customize what data the form implementing IObserver is pulling out of the publisher.
Of course if you ONLY want the Observer to be able to display a string list or specific data. Then pass it as part of the parameters. The Interface makes explicit what want each layer to do. This way 5 years from now you can look at the code and code "Oh that what it is doing."
(source: headfirstlabs.com)
As said Check out "Head First: Design Patterns" they also have some forums regarding the book and a design meditation.
Observer Pattern follow the Hollywood principle "Don't call us we call you"
Good site for patterns
http://www.dofactory.com/Patterns/PatternObserver.aspx
In it's very simplest terms, there are two components: Observer and Observed.
Externally, the Observed needs a way to add (register) and remove an Observer.
Internally, the Observed needs a list of registered Observers.
The observer needs a public method such as Notify() or Notify(params).
Any time a particular thing happens to the Observed, it will loop through the list and call Notify() on every registered observer.
In the simplest case, it's a simple notification that says "Hey, Observer, My Data Changed, come and refresh yourself"
In more complex versions, parameters can be past letting the observer know what has changed.
In a Model-View-Controller, the Observed is usually an entity object -- Something that holds data. The Controller is the Observer. It watches for changes in the Model, and tells the View to update itself if it is interested in the change.
Java event listeners are a real world implementation of this pattern.
Imagine that you have a object whose behavior (or state) you want to observe. For example, when field A hits value 10, you want to get informed on that event without actually getting coupled with the implementation details of this complex object you want to observe.
You define an interface, call it Observable and let your target implement this interface, it should have at least two methods to register and unregister an Observer, which in turn is the object which will get called by Observer when field A hits 10. Your Observer simply calls Observable to register (and unregister when done). Observable normally maintain a list of Observers and notifies them at once, or as you please. It can also be done synchronously or asynchronously, it's up to you. This is very simplistic explanation without writing code. Once you understand it, the implementations can differ in details to fit your particular needs.
Observer (Publish/Subscribe)
When an object changes state, it notifies other objects that have registered their interest at runtime.
The notifying object (publisher) sends an event (publication) to all its observers (subscribers).
In one sentence:
An object (the Subject) allows other objects (Observers) to sign up for notifications.
Practical example:
Let's say you've got an app and you want to let other devs build plugins.
You could create a PluginSubject class, and put a method on it called NotifyOrderCreated. Whenever a new order is created on your order screen, it calls PluginSubject.NotifyOrderCreated.
When that happens, the PluginSubject gets a list of PluginObservers and calls PluginObserver.Notify on each of them, passing in a message describing the event.
That enables some really neat functionality.
Way More Than You Want to Know:
I actually did this recently, so I will take the example one step deeper - if you require your Observers to implement a special interface, let's say IPluginObserver, you can use reflection to walk the types in your assembly and instantiate the plugins on the fly.
Then you can allow users to sign up their own assemblies (you have to store a list of assembly names somewhere and then walk it), and bam, you've got extensibility!
Observer is a means of decoupling, that is, loosening the connections between two objects. You want that because it makes your code neater and easier to maintain. That's pretty much the goal of all design patterns: easier to read, easier to maintain code.
In this pattern, you have two classes, two objects: publisher and observer. Publisher is a class that actually does some work, then it every so often will call methods on any observers to tell them about it. It knows which classes to call because it keeps a list of observers who subscribed.
So your Publisher might look something like this:
class Publisher
{
List<Observer> observers = new List<Observer>();
public Add(Observer o)
{
observers.Add(o);
}
private AlertObservers()
{
foreach(Observer o in observers)
{
o.Alert();
}
}
Publisher really does most of the work. All the Observer needs to do is get added to the list and implement the called method. Like so:
class Observer
{
public Observer(Publisher pub)
{
pub.Add(this);
}
public Alert()
{
System.Console.WriteLine("Oh no, stuff is happening!");
}
}
That's a pretty barebones idea of how it works. Now, why is that valuable? Looks pretty well coupled up huh? One reason for that is because I don't use an Interface, which would allow me to set up many classes with Observer functionality, and Publisher need never know anything more about them except that they can receive an Alert() call. Also note that Publisher will attempt to call Alert on any and all Observers it has, even if it has none.
Now, in the C# world, the language has a built in version of this pattern through it's Event objects. Events are very powerful and make use of Delegates, which is a way of passing a method as a parameter in another method call. They allow for some serious decoupling, but I'd save that for a new question.
Very few real time Examples:
Newspaper/Magazine/Mailing List
Subscription or any subscription in general
Tagging a colleague in MS Office
Communicator
Twitter
Those who've suggested that events in .NET really are an implementation of the Observer pattern aren't pulling your chain; it's true. As for how this actually works, both from a high level perspective and in terms of more implementation-specific details, I'll use an analogy.
Think of a newspaper publisher. In OOP terms we might think of a newspaper as an observable thing. But how does it work? Clearly the implementation details of the newspaper itself (that is, in this analogy, the journalists, writers, editors, etc. all working back at the office to put the newspaper together) are not publicly exposed. People (observers) do not gather together and watch the employees of the newspaper publisher doing their work. They can't just do that, because there is no protocol (or interface) in place for doing that.
This is how you observe (i.e., read) a newspaper: you subscribe to it. You get your name on a list of subscribers to that paper, and then the publisher knows to deliver one on your doorstep every morning. If you don't want to observe (read) it anymore, you unsubscribe; you get your name taken off that list.
Now, this might seem like an abstract analogy; but it's actually an almost perfect parallel to how .NET events work.
Given some class intended to be observable, its implementation in general need not be known to the public. However, it will expose a particular kind of interface to the public, and that interface is an event. Code that wants to observe this event essentially registers itself as a subscriber:
// please deliver this event to my doorstep
myObject.SomeEvent += myEventHandler;
When this same code decides it doesn't want to be notified of this event anymore, it unsubscribes:
// cancel my subscription
myObject.SomeEvent -= myEventHandler;
Now for a quick discussion of delegates and how this code actually works. A delegate, as you may or may not know, is essentially a variable that stores the address of a method. Typically, this variable has a type -- just like value variables declared as int, double, string, etc. all have types. In the case of delegate types, this type is defined by the method's signature; that is, its parameters and its return value. A delegate of a particular type can point to any method, that performs any action, as long as that method has the appropriate signature.
So to come back to the newspaper analogy: in order to successfully subscribe to a newspaper, you have to actually follow a particular pattern. Specifically, you need to provide a valid address where you want the newspaper delivered. You can't just say, "Yeah, send it to Dan." You can't say, "I'll have a bacon cheeseburger." You have to give the publisher information that they can meaningfully work with. In the world of .NET events, this translates to needing to supply an event handler of the correct signature.
In most cases, this signature ends up being some method like this:
public void SomeEventHandler(object sender, EventArgs e) {
// anything could go in here
}
The above is a method that could be stored in a delegate variable of type EventHandler. For more specific cases, there's the generic EventHandler<TEventArgs> delegate type, which desribes a method similar to the above, but with an e parameter of some type derived from EventArgs.
Keeping in mind that delegates are really variables pointing to methods, it isn't hard to make the final connection between .NET events and newspaper subscriptions. The way events are implemented is via a list of delegates, to/from which items may be added and removed. This is really just like a newspaper publisher's list of subscribers, each of whom receives a copy when the newspapers are distributed every morning.
Anyway, hopefully this has helped you get your head around the Observer pattern somewhat. There are many other kinds of implementations of this pattern, of course, but .NET events is a paradigm with which the majority of .NET developers are familiar, so I think it's a good starting point from which to develop one's understanding.

Categories

Resources