The purpose of delegates [duplicate] - c#

This question already has answers here:
Where do I use delegates? [closed]
(8 answers)
Closed 9 years ago.
Duplicate:
Difference between events and delegates and its respective applications
What are the advantages of delegates?
Where do I use delegates?
I wonder what the purpose of delegates is. I haven't used them that much and can't really think of something.
In my courses, it's written that a delegate is a blue-print for all methods that comply with its signature.
Also, you can add multiple methods to one delegate, and then they'll be executed after eachother in the order they were added. Which is probably only usefull for methods that affect local variables or methodes that don't return any values.
I've read that C# implements Events as delegates, which is documented as being:
//Summary: Represents the method that
will handle an event that has no event
data.
//Parameters:
//sender: The source of the event.
//e: An System.EventArgs that contains no event data.
[Serializable]
[ComVisible(true)]
public delegate void EventHandler(object sender, EventArgs e);
Still, it's kinda confusing. Can someone give a good, usefull example of this concept?

Yeah,
You're almost there. A delegate refers to a method or function to be called. .NET uses the Events to say.. when someones presses this button, I want you to execute this piece of code.
For example, in the use of a GPS application:
public delegate void PositionReceivedEventHandler(double latitude, double longitude);
This says that the method must take two doubles as the inputs, and return void. When we come to defining an event:
public event PositionReceivedEventHandler PositionReceived;
This means that the PositionRecieved event, calls a method with the same definition as the
PositionReceivedEventHandler delegate we defined. So when you do
PositionRecieved += new PositionReceivedEventHandler(method_Name);
The method_Name must match the delegate, so that we know how to execute the method, what parameters it's expecting. If you use a Visual Studio designer to add some events to a button for example, it will all work on a delegate expecting an object and an EventArgs parameter.
Hope that helps some...

As you noted a delegate is a way to create a signature for an method call. There are many great examples of using delegates, but the one that really opened my mind is this example.
public delegate Duck GetDuckDelegate();
public GetDuckDelegate GiveMeTheDuckFactoryMethod(string type)
{
switch(type)
{
case "Rubber":
return new GetDuckDelegate(CreateRubberDuck);
case "Mallard":
return new GetDuckDelegate(CreateMallardDuck);
default:
return new GetDuckDelegate(CreateDefaultDuck);
}
}
public Duck CreateRubberDuck()
{
return new RubberDuck();
}
public Duck CreateMallardDuck()
{
return new MallardDuck();
}
public Duck CreateDefaultDuck()
{
return new Duck();
}
Then to use it
public static void Main() {
var getDuck = GiveMeTheDuckFactoryMethod("Rubber");
var duck = getDuck();
}
Arguably, the Factory pattern would be a better method for this, but I just thought up this example on the fly and thought it proved the point of how delegates can be treated as objects

Delegates allow you to pass methods around like values.
For example, .Net has a method called Array.ForEach that takes a delegate and an array, and calls the delegate on each element of the array.
Therefore, you could write,
int[] arr = new int[] { 1, 2, 4, 8, 16, 32, 64 };
Array.ForEach(arr, new Action<int>(Console.WriteLine));
This code will call Console.WriteLine for each number in the array.
There are many things you can do by making functions that take delegates, especially when combined with anonymous methods. For examples, look at LINQ.

Many people initially get confused with the real need for delegates and events. I was one of them and it took me some time to figure it out :-). Recently answered a similar query in ASP.NET forums and thought it would be good if I create a blog post on this topic! Here was the query:
"I was reading an example somewhere of a Bank Class that if the minimum balance is reached you need to inform the rest of the app that the min has reached, but can't we do that by just calling a normal method.
for example: lets say when we deduct some amount from the balance and if minimum reached then call some method to take some action, I am totally missing why do we need delegates and custom events here?"
Thing is in the Bank case, you can definitely call a method, but then it would be simple procedural programming, we need event based programming when we want our code to respond to some events generated by a system.
For eg.: think that windows OS is a system, and we are writing a code (in any language) where we want to capture an event like mouse_click(). Now how would our program know that a mouse click has occured? We can use low level code for it, but since OS is already handling low level code, its best to capture an event raised by the OS.
In other terms, the moment a mouse_click() happens the OS fires an event. The OS doesnt care who captures this event and uses it, it just sends out a notification. Then any code (like ours) can capture that event and use it accordingly. This saves us a lot of time to write code for the same ourselves. And other programs too can use the same event and handle it accordingly.
Similarly, the banking system can be huge, and many other outside applications might be accessing it. The banking system does not know how many such applications there are which need it, or are dependent on it, and how would they handle certain situations like when balance is low, so it simply fires an event whenever low balance occurs, and this event can be used by any other code, besides banking code itself.
Note that each susbcriber to that event can handle that event independently, for eg. the banking code might stop something from executing if balance is low, some other reporting app might send an email in such a case, or some ATM code can stop a particualr transaction and notify the user that balance is low.
Hope this clears things a bit!

I can provide you with an example using a web application architecture:
Generally, with a web application you can provide a front controller that receives requests from many clients. We could put all our methods within the front controller for dealing with the many different types of requests from the clients. However, this get a little cumbersome. Instead we can use delegates to encapsulate functionality for different requests. We could have:
Authentication Delegate
User Management Delegate
and so on. So it's a neat way to split up functionality into logical chunks - delegates. The Struts framework is based on this way of working (the ActionServlet and Action classes).

There are lots of excellent articles explaining delegates - here are some good ones:
Delegates and events
C# Delegates Explained
Delegates in C#

Delegates, to my understanding, provides a way of specializing the behavior of a class without subclassing it.
Some classes have complex generic behavior, but are still meant to be specialized. Think of a Window class in a GUI framework: A Window can propably do a lot on it's own, but you would most likely still want to specialize it in some way. In some frameworks, this is done via inheritance. A different way of doing it is with delegates. Say you want something to happen when the Window resizes: Your delegate class can then implement a method called onWindowResize (provided of course that the Window class supports this), which gets called whenever the Window resizes and is responsible for any specialized behavior when the Window resizes.
I'm not going to argue the merits of delegation over inheritance, but suffice it to say that there are many who feel that delegation is "cleaner" than inheritance.

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.

Is this a scenario to use delegates?

I received a win-form application with following pseudo-code. Most of the current function codes are written in the code behind the forms as those functions interact with form controls.
loop through device connections
connect to a device
call a specific function, do some specific work
close the device connection
There are 10 different functions (entirely varied signatures from one another). First version of the application repeated step 1, 2, 4 for all the 10 functions. The second version optimized it by adding select case statement with numeric values to call the functions within device connection-loop.
However I feel that function delegates could improve this code.
But I am quite lost in making an analogue to the delegate concept with what I have in hand. Can I use delegates in this situation and how should I approach it in terms of the application execution/code design?
it's hard to tell having only the pseudo-code but IMO you don't need a delegate - either use Action<...> or Func<...> depending on if you need a result or not.
For example it could look something like this:
static void DoForAllDevices(Action<Connection> action)
{
foreach(var device in myDevices)
{
using (var connection = ConnectTo(device))
{
action(connection);
} // typically Dispose will handle the closing
}
}
then you just have to call it like this
DoForAllDevices(connection => myFirstFun(connection, additionalParameter);
now of course you can add all kind of exception-Handling, etc. inside DoForAllDevices - should be easy to do

Code-friendly version of event signature in .NET

Preceding posts:
Event Signature in .NET — Using a Strong Typed 'Sender'?
In a C# event handler, why must the “sender” parameter be an object?
Microsoft's conventions and guidelines force .NET users to use special pattern for creating, raising and handling events in .NET.
Event design guidelines http://msdn.microsoft.com/en-us/library/ms229011.aspx state that
Citation:
The event-handler signature observes the following conventions :
The return type is Void.
The first parameter is named sender
and is of type Object. This is the
object that raised the event.
The second parameter is named e and
is of type EventArgs or a derived
class of EventArgs.This is the
event-specific data.
The method takes exactly two
parameters.
These conventions tell developers that the (following) shorter and more obvious code is evil:
public delegate void ConnectionEventHandler(Server sender, Connection connection);
public partial class Server
{
protected virtual void OnClientConnected(Connection connection)
{
if (ClientConnected != null) ClientConnected(this, connection);
}
public event ConnectionEventHandler ClientConnected;
}
and the (following) longer and less obvious code is good:
public delegate void ConnectionEventHandler(object sender, ConnectionEventArgs e);
public class ConnectionEventArgs : EventArgs
{
public Connection Connection { get; private set; }
public ConnectionEventArgs(Connection connection)
{
this.Connection = connection;
}
}
public partial class Server
{
protected virtual void OnClientConnected(Connection connection)
{
if (ClientConnected != null) ClientConnected(this, new ConnectionEventArgs(connection));
}
public event ConnectionEventHandler ClientConnected;
}
Though these guidelines not state why is it so important to follow these conventions, making developers act like monkeys who don't know why and what are they doing.
IMHO, Microsoft's event signature conventions for .NET are bad for your code because they cause additional zero-efficiency effort to be spent on coding, coding, coding:
Coding "(MyObject)sender" casts (not speaking about 99% of situations that don't require sender at all)
Coding derived "MyEventArgs" for the data to be passed inside event handler.
Coding dereferences (calling "e.MyData" when the data is required instead of just "data")
It's not that hard to do this effort, but practically speaking what are we loosing when not conforming to Microsoft's conventions, except that people take you as an heretic because your act of confrontation to Microsoft's conventions verges on blasphemy :)
Do you agree?
The problems you will have:
When you add another argument, you
will have to change your event
handler signature.
When a programmer first looks at
your code, your event handlers will
not look like event handlers.
Especially the latter can waste you far more time than writing a 5 line class.
Regarding having a strongly-typed sender, I've often wondered that myself.
Regarding the EventArgs, I'd still recommend you use an intermediate EventArgs class because you may want to add event information in the future which you don't currently foresee. If you've used a specific EventArgs class all along, you can simply change the class itself and the code where it gets fired. If you pass the Connection as per your example, you'd have to refactor every event handler.
Edit
Jim Mischel made a good point in his comments. By making the sender an object, we enable the same event method to potentially be reused to handle a variety of events. For example, let's say that a grid needs to update itself if:
the user clicks a "refresh" button, or
the system detects that a new entry has been loaded from the server.
You could then say something like this:
serverBus.EntryReceived += RefreshNeededHandler;
refreshButton.Click += RefreshNeededHandler;
...
public void RefreshNeededHandler(object sender, EventArgs args)
{
...
}
Of course, in practice, I have pretty much never had any call for this kind of reuse, whereas the first thing I tend to to in many, many cases is cast the sender to the object type that I know it has to be. If I want to reuse handlers like this, I think it would be easy enough to make two handlers that both call the same convenience method. For me, an event handler is conceptually supposed to handle a specific type of event on a particular group of objects. So I am not personally convinced that the object sender approach is the best convention.
However, I can imagine cases where this would be extremely handy, like if you want to log every event that gets fired.
The biggest problem I see in not following the convention is that you're going to confuse developers who are used to handling events in the way that the runtime library does. I won't say that the convention is good or bad, but it's certainly not evil. .NET developers know and understand how to work with events that are written in conformance with Microsoft's guidelines. Creating your own event handling mechanism on top of that may be more efficient at runtime and might even lead to code that you think is cleaner. But it's going to be different and you'll end up with two event handling "standards" in your program.
My position is that it's better to use a single less-than-ideal standard (as long as it's not horribly broken) than to have two competing standards.
I used strongly typed events (instead of object as it saves me having to cast), it really isn't that hard to understand, "oh look they've used a type that isn't an object"
As for eventArgs, you should use this in case the object changes as per #StriplingWarrior answer.
I don't understand why devs would get confused over it?

C# -Priority based delegates and chaining in delegates possible? or Windows Work Flow?

Whenever i feel hungry i will publish i am hungry.This will be notified to the service providers say (MealsService,FruitService,JuiceService ).(These service providers know what to serve).
But the serving priority is the concern. Priority here means my first choice is MealsService when there are enough meal is available my need is end with MealsService.To verify the enough meal is availabe the MealsService raises the event "updateMeTheStockStatus" to the "MealsServiceStockUpdateListener" .
The "MealsServiceStockUpdateListener" will only reply back to "MealsService" . No other Service providers ( FruitService,JuiceService ) will be notified by the "MealsServiceStockUpdateListener" .If there is no sufficient stock then only the MealsService passes notification to the JuiceService (as it is the second priority).As usual it checks the stock.If stock is not sufficient it passes message to FruitService,so the flow continues like this.
How can i technically implement this?
Any implemention like priority based delagates and delegate chaining make sense ?
(Somebody! Please reframe it for good readability ).
Update : In this model there is no direct communication between "StackUpdateListener" and "me".Only The "Service Providers" will communicate me.
Like other answerers, I'm not entirely convinced that an event is the way forward, but let's go along with it for the moment.
It seems to me that the business with the MealsServiceStockUpdateListener is a red herring really - you're just trying to execute some event handlers but not others. This sort of thing crops up elsewhere when you have a "BeforeXXX" event which allows cancellation, or perhaps some sort of exception handling event.
Basically you need to get at each of your handlers separately. There are two different ways of doing that - either you can use a normal multicast delegate and call GetInvocationList() or you can change your event declaration to explicitly keep a list of handlers:
private List<EventHandler> handlers = new List<EventHandler>();
public event EventHandler MealRequired
{
add { handlers.Add(value); }
remove
{
int index = handlers.LastIndexOf(value);
if (index != -1)
{
handlers.RemoveAt(index);
}
}
}
These two approaches are not quite equivalent - if you subscribe with a delegate instance which is already a compound delegate, GetInvocationList will flatten it but the List approach won't. I'd probably go with GetInvocationList myself.
Now, the second issue is how to detect when the meal has provided. Again, there are two approaches. The first is to use the normal event handler pattern, making the EventArgs subclass in question mutable. This is the approach that HandledEventArgs takes. The second is to break the normal event pattern, and use a delegate that returns a value which can be used to indicate success or failure (and possibly other information). This is the approach that ResolveEventHandler takes. Either way, you execute the delegates in turn until one of them satistfies your requirements. Here's a short example (not using events per se, but using a compound delegate):
using System;
public class Test
{
static void Main(string[] args)
{
Func<bool> x = FirstProvider;
x += SecondProvider;
x += ThirdProvider;
Execute(x);
}
static void Execute(Func<bool> providers)
{
foreach (Func<bool> provider in providers.GetInvocationList())
{
if (provider())
{
Console.WriteLine("Done!");
return;
}
}
Console.WriteLine("No provider succeeded");
}
static bool FirstProvider()
{
Console.WriteLine("First provider returning false");
return false;
}
static bool SecondProvider()
{
Console.WriteLine("Second provider returning true");
return true;
}
static bool ThirdProvider()
{
Console.WriteLine("Third provider returning false");
return false;
}
}
Rather than publish a message "I'm hungry" to the providers, publish "I need to know current stock available". Then listen until you have enough information to make a request to the correct food service for what you need. This way the logic of what-makes-me-full is not spread amongst the food services... It seems cleaner to me.
Message passing isn't baked into .NET directly, you need to implement your own message forwarding by hand. Fortunately, the "chain of responsiblity design pattern" is designed specifically for the problem you're trying to solve, namely forwarding a message down a chain until someone can handle it.
Useful resources:
Chain of Responsibility on Wikipedia
C# implementation on DoFactory.com
I'm not sure if you really need a priority event. Anyways, let's suppose we want to code that just for fun.
The .NET Framework has no support for such a peculiar construct. Let me show one possible approach to implement it.
The first step would be to create custom store for event delegates (like described here);
Internally, the custom event store could work like a priority queue;
The specific EventArgs used would be HandledEventArgs (or a subclass of it). This would allow the event provider to stop calling handlers after one of them sets the event as Handled;
The next step is the hardest. How to say to tell the event provider what is the priority of the event handler that is being added?
Let me clarify the problem. Usually, the adding of a handler is like this:
eater.GotHungry += mealsService.Someone_GotHungry;
eater.GotHungry += juiceService.Someone_GotHungry;
eater.GotHungry += fruitService.Someone_GotHungry;
The += operator will only receive an delegate. It's not possible to pass a second priority parameter. There might be several possible solutions for this problem. One would be to define the priority in a custom attribute set at the event handler method. A scond approach is discussed in the question.
Compared to the chain of responsibility implementation at dofactory.com, this approach has some advantages. First, the handlers (your food services) do not need to know each other. Also, handlers can be added and remove at any time dynamically. Of course, you could implement a variation of a chain of responsibility that has this advantages too.
I don't think delegates are the proper solution to your problem. Delegates are a low-level service provided by C# for relatively tightly coupled events between components. If I understand your question properly (It is worded a little oddly, so I am not sure I clearly understand your problem), then I think what you need is a mediated consumer/provider.
Rather than having your consumers directly consume the meal, juice, and fruit providers, have them request a food item from a central mediator. The mediator would then be responsible for determining what is available and what should be provided to the consumer. The mediator would be a subscriber to events published by all three services. Whenever stock is added/updated in the Meal, Juice, or Fruit services, they would publish their current stock to all subscribers. The mediator, being a subscriber, would track current stock reductions on its own, and be able to determine for itself whether to send a meal, juice, or fruit to a food consumer when a get food request is made.
For example:
|---------- (GetFoodResponse) ----------------
V |
FoodConsumer ---- (GetFoodRequest) ------> FoodProvider <-----> [ Local Stock Data ]
^
|
|
MealService ---- (PublishStockMessage) ----------|
^
JuiceService --- (PublishStockMessage) ----------|
^
FruitService --- (PublishStockMessage) ----------|
The benefits of such a solution are that you reduce coupling, properly segregate responsibility, and solve your problem. For one, your consumers only need to consume a single service...the FoodProvider. The FoodProvider subscribes to publications from the other three services, and is responsible for determining what food to provide to a consumer. The three food services are not responsible for anything related to the hunger of your food consumers, they are only responsible for providing food and tracking the stock of the food they provide. You also gain the ability to distribute the various components. Your consumers, the food provider, and each of the three food services can all be hosted on different physical machines if required.
However, to achieve the above benefits, your solution becomes more complex. You have more parts, and they need to be connected to each other properly. You have to publish and subscribe to messages, which requires some kind of supporting infrastructure (WCF, MSMQ, some third party ESB, custom solution, etc.) You also have duplication of data, since the food provider tracks stock on its own in addition to each of the food services, which could lead to discontinuity in available stock. This can be mitigated if you manage stock updated properly, but that would also increase complexity.
If you can handle the additional complexity, ultimately, a solution like this would more flexible and adaptable than a more tightly connected solution that uses components and C# events in a local-deployment-only scenario (as in your original example.)
I am having a bit of trouble understanding your analogy here, which sounds like you're obscuring the actual intent of the software, but I think I have done something like what you are describing.
In my case the software was telemarketing software and each of the telemarketers had a calling queue. When that queue raises the event signifying that it is nearing empty, the program will grab a list of available people to call, and then pass them through a chain of responsibility which pushes the available call into the telemarketer's queue like so:
Each element in the chain acts as a priority filter: the first link in the chain will grab all of the people who have never been called before, and if it finishes (ie. went through all of the people who have never been called) without filling up the queue, it will pass the remaining list of people to call to the next link in the chain - which will apply another filter/search. This continues until the last link in the chain which just fires off an e-mail to an administrator indicating that there are no available people to be called and a human needs to intervene quickly before the telemarketers have no work to do.

When would I use a delegate in asp.net?

I'm always looking for a way to use all the tools I can and to stretch myself just beyond where I am at. But as much as I have read about delegates, I can never find a place to use them (like Interfaces, Generics, and a lot of stuff, but I digress.) I was hoping someone could show me when and how they used a delegate in web programming for asp.net c#(2.0 and above).
Thank you and if this wrong for Stack Overflow, please just let me know.
bdukes is right about events. But you're not limited to just using delegates with events.
Study the classic Observer Pattern for more examples on using delegates. Some text on the pattern points toward an event model, but from a raw learning perspective, you don't have to use events.
One thing to remember: A delegate is just another type that can be used & passed around similar to your primitive types such as an "int". And just like "int", a delegate has it's own special characteristics that you can act on in your coding when you consume the delegate type.
To get a really great handle on the subject and on some of it's more advanced and detailed aspects, get Joe Duffy's book, .NET Framework 2.0.
Well, whenever you handle an event, you're using a delegate.
To answer your second question first, I think this is a great question for StackOverflow!
On the first, one example would be sorting. The Sort() method on List takes a delegate to do the sorting, as does the Find() method. I'm not a huge fan of sorting in the database, so I like to use Sort() on my result sets. After all, the order of a list is much more of a UI issue (typically) than a business rule issue.
Edit: I've added my reasons for sorting outside the DB to the appropriate question here.
Edit: The comparison function used in the sort routine is a delegate. Therefore, if you sort a List using the .Sort(Comparison(T)) method the Comparison(T) method you pass to the sort function is a delegate. See the .Sort(Comparison(T)) documentation.
Another quick example off the top of my head would be unit testing with Rhino Mocks. A lot of the things you can do with Rhino Mocks utilize delegates and lambda expressions.
You can use delegates whenever you know you will want to take some action, but the details of that action will depend on circumstances.
Among other things, we use delegates for:
Sorting and filtering, especially if the user can choose between different sorting/filtering criteria
Simplifying code. For example, a longish process where the beginning and end are always the same, but a small middle bit varies. Instead of having a hard-to-read if block in the middle, I have one method for the whole process, and pass in a delegate (Action) for the middle bit.
I have a very useful ToString method in my presentation layer which converts a collection of anything into a comma-separated list. The method parameters are an IEnumerable and a Func delegate for turning each T in the collection into a string. It works equally well for stringing together Users by their FirstName or for listing Projects by their ID.
There isn't anything special to asp.net related to delegates (besides considerations when using async stuff, which is a whole different question), so I will point you to other questions instead:
Delegate Usage : Business Applications
Where do I use delegates?
Another example would be to publish events for user controls.
Eg.
// In your user control
public delegate void evtSomething(SomeData oYourData);
public event evtSomething OnSomething;
// In the page using your user control
ucYourUserControl.OnSomething += ucYourUserControl_OnSomething;
// Then implement the function
protected void ucYourUserControl_OnSelect(SomeData oYourData)
{
...
}
Recently i used the delegates for "delegating" the checking of the permissions.
public Func CheckPermission;
This way, the CheckPermission function can be shared by various controls or classes, say it in a static class or a utilities class, and still be managed centralized, avoiding also Interface explossion; just a thought

Categories

Resources