I am trying to understand the delegates and events, so far I know the concepts.
I have a question in mind and want to know if I am right.
There is a class Car. We create a public delegate (CarHandler), then we create a private member of delegate type (ListofMethods), then we create method for registering methods with this member (RegistorMethods) in this we say ListofMethods+=incoming parameter.
Then, in main program we create methods with signature same as that of the delegate(signature is return type void and parameter is string). Then, we create object of Car class. Then we register the method/methods with the delegate (method is console.writeline(incomming parameter)). Then when we invoke this class. Now, based on where in the class the ListofMethods is invoked (example:ListofMethods("Hey There");), accordingly the RegistoredMethods will fire.
So the advantage of using events instead of above example is that :
I know that we can create multiple events of the same delegate type with out creating more registration methods.
Case 1 is using only delegates and no events. And case 2 is using events. Then, In case 1, all the registered methods would get the same text as invoked by ListofHandler. To create more events (events here mean the general english meaning and not the c# events) in Case 1 we would need to create more delegate members, more methods for registering new methods with this delegate member. However, in Case of EVENTS (case 2) the different events can give their own text and the instance can then register with the event it needs and it will get it fired.
In CASE 1 we would need to create more delegate members for raising multiple events(not C# events, general English meaning), where as in case of CASE 2 (events) it is enough to create only 1 delegate member. Is that right?
Question:
Is the above para correct way to implement a CASE 3, that is like case 2, but only using delegates and not events. Please can you write a note on this in your answer
If not understood then you can ask me question. Please help me clear my doubt here.
Code for CASE 1:
public class Car
{
// 1) Define a delegate type.
public delegate void CarEngineHandler(string msgForCaller);
// 2) Define a member variable of this delegate.
//this can be public, and if public then we can avoid writing the below RegisterWithCarEngine method, but it is not safe
//because user can mess the values and call custom strings, etc
private CarEngineHandler listOfHandlers;
// 3) Add registration function for the caller.
public void RegisterWithCarEngine(CarEngineHandler methodToCall)
{
//listOfHandlers = methodToCall;
listOfHandlers += methodToCall;
}
// Internal state data.
public int CurrentSpeed { get; set; }
public int MaxSpeed { get; set; }
public string PetName { get; set; }
// Is the car alive or dead?
private bool carIsDead;
// Class constructors.
public Car()
{
MaxSpeed = 100;
}
public Car(string name, int maxSp, int currSp)
{
CurrentSpeed = currSp;
MaxSpeed = maxSp;
PetName = name;
}
// 4) Implement the Accelerate() method to invoke the delegate's
// invocation list under the correct circumstances.
public void Accelerate(int delta)
{
// If this car is "dead," send dead message.
if (carIsDead)
{
if (listOfHandlers != null)
listOfHandlers("Sorry, this car is dead...");
}
else
{
CurrentSpeed += delta;
// Is this car "almost dead"?
if (10 == (MaxSpeed - CurrentSpeed) && listOfHandlers != null)
{
listOfHandlers("Careful buddy! Gonna blow!");
}
if (CurrentSpeed >= MaxSpeed)
carIsDead = true;
else
Console.WriteLine("CurrentSpeed = {0}", CurrentSpeed);
}
}
}
class Program
{
static void Main(string[] args)
{
Console.WriteLine("***** Delegates as event enablers *****\n");
// First, make a Car object.
Car c1 = new Car("SlugBug", 100, 10);
// Now, tell the car which method to call
// when it wants to send us messages.
c1.RegisterWithCarEngine(new Car.CarEngineHandler(OnCarEngineEvent));
// Speed up (this will trigger the events).
Console.WriteLine("***** Speeding up *****");
for (int i = 0; i < 6; i++)
c1.Accelerate(20);
Console.ReadLine();
Car c2 = new Car("SlugBug1", 100, 10);
// Speed up (this will trigger the events).
Console.WriteLine("***** Speeding up *****");
for (int i = 0; i < 6; i++)
c2.Accelerate(20);
Console.ReadLine();
}
// This is the target for incoming events.
public static void OnCarEngineEvent(string msg)
{
Console.WriteLine("\n***** Message From Car Object *****");
Console.WriteLine("=> {0}", msg);
Console.WriteLine("***********************************\n");
}
}
Code for CASE 2:
public class Car
{ // This delegate works in conjunction with the
// Car's events.
public delegate void CarEngineHandler(string msg);
// This car can send these events.
public event CarEngineHandler Exploded;
public event CarEngineHandler AboutToBlow;
...
}
public void Accelerate(int delta)
{
// If the car is dead, fire Exploded event.
if (carIsDead)
{
if (Exploded != null)
Exploded("Sorry, this car is dead...");
}
else
{ CurrentSpeed += delta;
// Almost dead?
if (10 == MaxSpeed - CurrentSpeed && AboutToBlow != null)
{
AboutToBlow("Careful buddy! Gonna blow!");
}
// Still OK!
if (CurrentSpeed >= MaxSpeed)
carIsDead = true;
else
Console.WriteLine("CurrentSpeed = {0}", CurrentSpeed);
}
}
static void Main(string[] args)
{
Console.WriteLine("***** Fun with Events *****\n");
Car c1 = new Car("SlugBug", 100, 10);
// Register event handlers.
c1.AboutToBlow += CarIsAlmostDoomed;
c1.AboutToBlow += CarAboutToBlow;
c1.Exploded += CarExploded;
Console.WriteLine("***** Speeding up *****");
for (int i = 0; i < 6; i++)
c1.Accelerate(20);
c1.Exploded -= CarExploded;
Console.WriteLine("\n***** Speeding up *****");
for (int i = 0; i < 6; i++)
c1.Accelerate(20);
Console.ReadLine();
public static void CarAboutToBlow(string msg) { Console.WriteLine(msg); }
public static void CarIsAlmostDoomed(string msg) { Console.WriteLine("=> Critical Message from Car: {0}", msg); }
public static void CarExploded(string msg) { Console.WriteLine(msg); }
}
Your two cases are nearly identical. The only material difference is that when you use an event in your class (i.e. "case 2"), and you don't implement it explicitly, the compiler automatically generates the field that you would have had to declare in "case 1", as well as the method to allow subscription/registration.
Something that often surprises people, even occasionally those who have been using C# for some time, is a statement like mine above:
and you don't implement it explicitly
What's that statement mean? Many people don't realize that, as with a property, it is possible to either let the compiler implement the member, or to do it yourself.
In the case of the property, you implement a get and/or a set method. In the case of an event, the methods are named add and remove. And of course, if you implement it yourself, you need to also provide the backing field or other mechanism to track subscribers (just like in a property).
So, what's this all mean in your specific example? Well, to me it means that if you have event-like semantics, then you definitely should just go ahead and implement that as an actual event member. The code will all basically compile down to equivalent IL regardless of which way you do it, but using an event takes advantage of the language's high-level abstraction. This makes the code easier both to read and write, and so makes it more maintainable and less likely to contain bugs.
You can keep in mind the approach in "case 1", in case you wind up in a situation where declaring an event doesn't work (e.g. some kind of interop with a platform or API that doesn't deal with or support the .NET event paradigm). But in most situations, event is the way to go.
It seems that part of your concern is the question of the delegate members (i.e. the declared delegate types). Frankly, you have this issue regardless of which way you approach the problem. If you have a way of reusing a single delegate type for multiple event members in a class, then you can also reuse that single delegate type for the explicit field-and-registration-method approach ("case 1").
In most cases, you should not be declaring your own delegate type anyway. Just use e.g. EventHandler<T>, or one of the general purpose Action or Func types.
The difference between your two cases basically boil down to this difference:
Case 1
public class Car
{
void RegisterWithCarEngine(CarEngineHandler methodToCall);
}
Case 2
public class Car
{
event CarEngineHandler Exploded;
event CarEngineHandler AboutToBlow;
}
Case 1 is rather odd. There is nothing there to let a consumer of this class know what this method does - or when it will fire. Also, and perhaps more importantly, there is no way to detach then event handler.
Case 2 is more standard. It fits with the concept of giving a good naming convention and it is clear that these two members are events. It is therefore obvious to a consumer that they can attach and detach to these events.
You need to think about it a bit like if this where your design:
public class Car
{
void SetSpeed(string speedName, int speed);
int GetSpeed(string speedName);
}
I might then code it like this:
car.SetSpeed("Max", 50);
car.SetSpeed("Current", 10);
Console.WriteLine(car.GetSpeed("Max"));
Console.WriteLine(car.GetSpeed("Current"));
Now while this provide nominally the same functionality as your class - and same may argue that it offers even more functionality - it hides the functionality as seen by a consumer of the class.
It is far better to go with the interface provided by Case 2.
Just as a side note, you should always call your event code like this:
var x = Exploded;
if (x != null)
x("Sorry, this car is dead...");
It is possible that the delegates on Exploded can be removed between the null check and the call. The temporary assignment prevents that issue.
Related
I would like to understand if/when to use delegates and interfaces in my code. The structure is pretty simple. The main class initialize a windows form:
class MainClass
{
public static void Main()
{
InputForm InputForm1 = new InputForm();
InputForm1.ShowDialog(); // show interface to prompt user
}
}
And the class for the form has a button and few more methods:
public partial class InputForm : Form
{
public InputForm()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
// do some calculation and then create a dictionary of items
for (int n = 1; n <= dict.Count; n++) // loop through items
{
dict[n].calculatedLength = theLength.calcLength(arg1, arg2, dict[n].speed);
}
}
}
When the button is clicked, the program does some calculation (calling methods in the same class InputForm) and save results into a dictionary (dict). Each element is an animal and I have some properties that I store in the dictionary (e.g. under the key "Dog" I have an average weight of dogs, an average speed, etc.).
Using the speed and two default arguments (arg1 that is the number of hours and arg2 that is the number of minutes) I have to call the method of the class LengthClass in order to get the estimated length that is covered by the specific animal in arg1 hours and arg2 minutes.
The LengthClass is like this:
class LengthClass
{
static double calcLength(double arg1, double arg2, double speed)
{
// do some calculation
return x;
}
}
Now the question: is there space in this example to use delegates and interfaces? Can you please show me how to best do it and what are the advantages/disadvantages in doing so instead of calling the calcLength method directly as I'm doing?
EDITED: I included the Microsoft guideline
Microsoft Guideline
Both delegates and interfaces enable a class designer to separate type declarations and implementation. A given interface can be inherited and implemented by any class or struct. A delegate can be created for a method on any class, as long as the method fits the method signature for the delegate. An interface reference or a delegate can be used by an object that has no knowledge of the class that implements the interface or delegate method. Given these similarities, when should a class designer use a delegate and when should it use an interface?
Use a delegate in the following circumstances:
An eventing design pattern is used.
It is desirable to encapsulate a static method.
The caller has no need to access other properties, methods, or
interfaces on the object implementing the method.
Easy composition is desired.
A class may need more than one implementation of the method.
Use an interface in the following circumstances:
There is a group of related methods that may be called.
A class only needs one implementation of the method.
The class using the interface will want to cast that interface to
other interface or class types.
The method being implemented is linked to the type or identity of the
class: for example, comparison methods.
The original answer (What I think)
Interfaces and delegates were made to make things easier when two classes have the same proprieties/behaviours.
I think that if you had something like that
private void Button(object sender, EventArgs e)
{
List<IAnimal> animals = Farm.GetAnimals();
foreach(IAnimal animal in animals)
{
dict[animal.name] = LeghtClass.CalculateLenght(animal);
//dict[animal.name] = animal.CalculateOwnLenght(); //using a method in the interface
}
}
You wouldn't have to worry about passing the method its parameters (wichh would help you when refactoring).
interface IAnimal
{
double Hours;
double Minutes;
double GrowSpeed;
//void CalculateOwnLenght();
}
And your lenght class would calculate it like that:
class LengthClass
{
static double calcLength(IAnimal animal)
{
return (animal.Hours + animal.Minutes / 60) * animal.GrowSpeed;
}
}
I can't think how delegates would help you unless if you do something like that:
foreach(var animal in animals)
{
delegate = animal.CalculateOwnLeght;
dict[animal.name] = delegate();
}
Ok, I have shown some code without saying anything.
I think interfaces are useful if you use them in more than one place, otherwise it can be messy - you just repeat youself more when using interfaces.
I personally don't think your way is wrong but I've read people saying that static is bad practise without proving why in a way I could understand, the one thing I remember is that it gets confusing easily and uses more resources.
I'd use delegates when I have to point to some method but I don't know the object of untill the code is running (they don't have mush use for this case, I think).
delegate void Cry();
...
cat = new Cat(); dog = new Dog();
...
foreach(var animal in animals)
{
if (animal is Cat)
{
Cry = cat.meow;
}
else if (animal is Dog)
{
Cry = dog.bark;
}
else {...}
if (animal.isInPain)
{
Cry();
}
}
I was reading some article which was describing the use of delegates by the following example
which shows the use of multicast delegate
public delegate void ProgressReporter(int percentComplete);
class Program
{
static void Main(string[] args)
{
ProgressReporter p = WriteProgressToConsole;
p += WriteProgressToFile;
Utility.HardWork();
}
private static void WriteProgressToConsole(int percentComplete)
{
Console.WriteLine(percentComplete);
}
private static void WriteProgressToFile(int percentComplete)
{
System.IO.File.WriteAllText("progress.txt", percentComplete.ToString());
}
}
public static class Utility
{
public static void HardWork(ProgressReporter p)
{
for (int i = 0; i < 10; i++)
{
p(i);
System.Threading.Thread.Sleep(1000);
}
}
}
But from my understanding of the code I think same can be done using a class and having the same functions which define the tasks done by delegate handlers as follows
public static class ProgressReporter
{
public static void WriteProgressToConsole(int percentComplete)
{
Console.WriteLine(percentComplete);
}
public static void WriteProgressToFile(int percentComplete)
{
System.IO.File.WriteAllText("progress.txt", percentComplete.ToString());
}
}
and changing the Utility class HardWork() as follows
public static class Utility
{
public static void HardWork()
{
for (int i = 0; i < 10; i++)
{
ProgressReporter.WriteProgressToConsole(i * 10);
ProgressReporter.WriteProgressToFile(i * 10);
System.Threading.Thread.Sleep(1000);
}
}
}
So my question with respect to this code is, why do we actually need a delegate in first place?
Some of the reasons(plz correct if I am wrong) which I think we need the delegate are as follows-
If we need notification in the Program class itself, then we need delegates.
With the help of multicast delegate we can call multiple functions at the same time in place of calling them multiple times(as in my second case).
A delegate is a way to have a reference to a particular method as a variable, meaning it can change, instead of as your last example, hardcoding into the program which methods to call.
Are there way to do this without delegates? Sure, you can provide objects that override methods or use classes that implements interfaces, but delegates are cheaper in the sense that you don't need a whole type wrapped around the single method.
Examples of situations where hardcoding won't do, and interfaces/overriding methods would be more work than delegates, try looking at visual components and their events. Events in .NET use delegates. You can simply double-click on a button in the visual designer in Visual Studio and it will create the method for you and wire it up to the event by the way of a delegate. Having to create a class, or implement an interface on top of the form class would be a lot more work, and especially if you have multiple buttons that you would want to do different things, then you definitely need multiple objects implementing those interfaces.
So delegates have their place, but your examples doesn't do them justice.
Here is a LINQPad example that demonstrates that one method (DoSomething) can end up doing different things depending on the delegate provided to it:
void Main()
{
DoSomething(msg => Console.WriteLine(msg));
using (var writer = new StreamWriter(#"d:\temp\test.txt"))
{
DoSomething(msg => writer.WriteLine(msg));
}
}
public delegate void LogDelegate(string message);
public static void DoSomething(LogDelegate logger)
{
logger("Starting");
for (int index = 0; index < 10; index++)
logger("Processing element #" + index);
logger("Finishing");
}
This will first log to the console, then rerun the method and log to a file.
Use a delegate in the following circumstances
1.An eventing design pattern is used (Event handlers )
2.A class may need more than one implementation of the method
3.Thread implementation (Thread Start, sleep etc )
for more info refer
https://msdn.microsoft.com/en-us/library/ms173173.aspx:
In C#, you can have a return value in your event function. However, you only receive the return value of the last event. Also, there doesn't appear to be a way to get the return value of the previous event.
What are some good practices? Should I always use void? From my limited experience if I want to chain values must I use ref?
How might I write an event? I wanted to use Func<ref t, returnT>, but ref is illegal there, and I imagine action is the same way. (I ended up with the below). Is there a way to make the event one line instead of two when using a ref?
delegate int FuncType(ref int a);
static event FuncType evt;
static void Main(string[] args)
{
evt += foo;
var aa = 1;
var a = evt(ref aa);
evt += bar;
var bb = 1;
var b = evt(ref bb);
}
static int foo(ref int a)
{
a = a*3;
return a;
}
static int bar(ref int a)
{
a=a +1;
return a;
}
As said you can use GetInvocationList which will allow you to call each method individually and process returned data.
But before that please consider using EventHandler<T> with EventArgs.
You can have "everything" you need to be returned in EventArgs.
Check this sample code :
public class BalanceChangedEventArgs : EventArgs
{
public readonly double OldBalance;
public readonly double NewBalance;
public BalanceChangedEventArgs(double oldB, double newB)
{
OldBalance = oldB;
NewBalance = newB;
}
}
public class Account
{
private double balance;
public EventHandler<BalanceChangedEventArgs> balanceChanged;
protected void OnBalanceChanged(BalanceChangedEventArgs eArgs)
{
if (balanceChanged != null)
balanceChanged(this, eArgs);
}
public double Balance
{
get { return balance; }
set
{
if (balance == value)
return;
OnBalanceChanged(new BalanceChangedEventArgs(balance, value));
balance = value;
}
}
}
Don't confuse "event" with "callback". If you're wanting to provide a "hook" for customization, then consider one of the following:
A base class with virtual methods for hooks.
An interface for a callback object passed in to your constructor or accessed via a property.
A delegate passed in to your constructor or accessed via a property.
If you've considered the above, and still want to use an event, then you could include the "result" as part of your event argument type, e.g., e.Result or e.Handled. You still have the issue of multiple event handlers possibly overwriting each other's values, so you should combine that approach with iterating the invocation list as suggested by other answers. Either collate all the results or have an "early exit" strategy like what is used for e.Handled.
You may want to look at Microsoft's documentation for Event Design.
If you want to get the return values when an event has multiple subscribers, use Delegate.GetInvocationList. Then you can say
foreach(FuncType d in evt.GetInvocationList()) {
int value = d(parameter);
// do something with value
}
However, in general, it's best to avoid return values in event handlers.
The 'best practice' is to only use void eventhandlers. Precisely because of the last-value-only problem.
If you want combined results, define an EventArgs descendant with appropriate properties. Use a list or sum values or something.
This question already has answers here:
Closed 12 years ago.
Possible Duplicates:
When would you use delegates in C#?
The purpose of delegates
I have seen many question regarding the use of delegates. I am still not clear where and WHY would you use delegates instead of calling the method directly.
I have heard this phrase many times: "The delegate object can then be passed to code which can call the referenced method, without having to know at compile time which method will be invoked."
I don't understand how that statement is correct.
I've written the following examples. Let's say you have 3 methods with same parameters:
public int add(int x, int y)
{
int total;
return total = x + y;
}
public int multiply(int x, int y)
{
int total;
return total = x * y;
}
public int subtract(int x, int y)
{
int total;
return total = x - y;
}
Now I declare a delegate:
public delegate int Operations(int x, int y);
Now I can take it a step further a declare a handler to use this delegate (or your delegate directly)
Call delegate:
MyClass f = new MyClass();
Operations p = new Operations(f.multiply);
p.Invoke(5, 5);
or call with handler
f.OperationsHandler = f.multiply;
//just displaying result to text as an example
textBoxDelegate.Text = f.OperationsHandler.Invoke(5, 5).ToString();
In these both cases, I see my "multiply" method being specified. Why do people use the phrase "change functionality at runtime" or the one above?
Why are delegates used if every time I declare a delegate, it needs a method to point to? and if it needs a method to point to, why not just call that method directly? It seems to me that I have to write more code to use delegates than just to use the functions directly.
Can someone please give me a real world situation? I am totally confused.
Changing functionality at runtime is not what delegates accomplish.
Basically, delegates save you a crapload of typing.
For instance:
class Person
{
public string Name { get; }
public int Age { get; }
public double Height { get; }
public double Weight { get; }
}
IEnumerable<Person> people = GetPeople();
var orderedByName = people.OrderBy(p => p.Name);
var orderedByAge = people.OrderBy(p => p.Age);
var orderedByHeight = people.OrderBy(p => p.Height);
var orderedByWeight = people.OrderBy(p => p.Weight);
In the above code, the p => p.Name, p => p.Age, etc. are all lambda expressions that evaluate to Func<Person, T> delegates (where T is string, int, double, and double, respectively).
Now let's consider how we could've achieved the above without delegates. Instead of having the OrderBy method take a delegate parameter, we would have to forsake genericity and define these methods:
public static IEnumerable<Person> OrderByName(this IEnumerable<Person> people);
public static IEnumerable<Person> OrderByAge(this IEnumerable<Person> people);
public static IEnumerable<Person> OrderByHeight(this IEnumerable<Person> people);
public static IEnumerable<Person> OrderByWeight(this IEnumerable<Person> people);
This would totally suck. I mean, firstly, the code has become infinitely less reusable as it only applies to collections of the Person type. Additionally, we need to copy and paste the very same code four times, changing only 1 or 2 lines in each copy (where the relevant property of Person is referenced -- otherwise it would all look the same)! This would quickly become an unmaintainable mess.
So delegates allow you to make your code more reusable and more maintainable by abstracting away certain behaviors within code that can be switched in and out.
.NET Delegates: A C# Bedtime Story
Delegates are extremely useful, especially after the introduction of linq and closures.
A good example is the 'Where' function, one of the standard linq methods. 'Where' takes a list and a filter, and returns a list of the items matching the filter. (The filter argument is a delegate which takes a T and returns a boolean.)
Because it uses a delegate to specify the filter, the Where function is extremely flexible. You don't need different Where functions to filter odd numbers and prime numbers, for example. The calling syntax is also very concise, which would not be the case if you used an interface or an abstract class.
More concretely, Where taking a delegate means you can write this:
var result = list.Where(x => x != null);
...
instead of this:
var result = new List<T>();
foreach (var e in list)
if (e != null)
result.add(e)
...
Why are delegates used if everytime I
declare a delegate, it needs a method
to point to? and if it needs a method
to point to, why not just call that
method directly?
Like interfaces, delegates let you decouple and generalize your code. You usually use delegates when you don't know in advance which methods you will want to execute - when you only know that you'll want to execute something that matches a certain signature.
For example, consider a timer class that will execute some method at regular intervals:
public delegate void SimpleAction();
public class Timer {
public Timer(int secondsBetweenActions, SimpleAction simpleAction) {}
}
You can plug anything into that timer, so you can use it in any other project or applications without trying to predict how you'll use it and without limiting its use to a small handful of scenarios that you're thinking of right now.
Let me offer an example. If your class exposes an event, it can be assigned some number of delegates at runtime, which will be called to signal that something happened. When you wrote the class, you had no idea what delegates it would wind up running. Instead, this is determined by whoever uses your class.
One example where a delegate is needed is when you have to modify a control in the UI thread and you are operating in a different thread. For example,
public delegate void UpdateTextBox(string data);
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
...
Invoke(new UpdateTextBox(textBoxData), data);
...
}
private void textBoxData(string data)
{
textBox1.Text += data;
}
In your example, once you've assigned a delegate to a variable, you can pass it around like any other variable. You can create a method accepting a delegate as a parameter, and it can invoke the delegate without needing to know where the method is really declared.
private int DoSomeOperation( Operations operation )
{
return operation.Invoke(5,5);
}
...
MyClass f = new MyClass();
Operations p = new Operations(f.multiply);
int result = DoSomeOperation( p );
Delegates make methods into things that you can pass around in the same way as an int. You could say that variables don't give you anything extra because in
int i = 5;
Console.Write( i + 10 );
you see the value 5 being specified, so you might as well just say Console.Write( 5 + 10 ). It's true in that case, but it misses the benefits for being able to say
DateTime nextWeek = DateTime.Now.AddDays(7);
instead of having to define a specifc DateTime.AddSevenDays() method, and an AddSixDays method, and so on.
To give a concrete example, a particularly recent use of a delegate for me was SendAsync() on System.Net.Mail.SmtpClient. I have an application that sends tons and tons of email and there was a noticeable performance hit waiting for the Exchange server to accept the message. However, it was necessary to log the result of the interaction with that server.
So I wrote a delegate method to handle that logging and passed it to SendAsync() (we were previously just using Send()) when sending each email. That way it can call back to the delegate to log the result and the application threads aren't waiting for the interaction to finish before continuing.
The same can be true of any external IO where you want the application to continue without waiting for the interaction to complete. Proxy classes for web services, etc. take advantage of this.
You can use delegates to implement subscriptions and eventHandlers.
You can also (in a terrible way) use them to get around circular dependencies.
Or if you have a calculation engine and there are many possible calculations, then you can use a parameter delegate instead of many different function calls for your engine.
Did you read http://msdn.microsoft.com/en-us/library/ms173171(VS.80).aspx ?
Using your example of Operations, imagine a calculator which has several buttons.
You could create a class for your button like this
class CalcButton extends Button {
Operations myOp;
public CalcButton(Operations op) {
this.myOp=op;
}
public void OnClick(Event e) {
setA( this.myOp(getA(), getB()) ); // perform the operation
}
}
and then when you create buttons, you could create each with a different operation
CalcButton addButton = new CalcButton(new Operations(f.multiply));
This is better for several reasons. You don't replicate the code in the buttons, they are generic.
You could have multiple buttons that all have the same operation, for example on different panels or menus. You could change the operation associated with a button on the fly.
Delegates are used to solve an Access issue. When ever you want to have object foo that needs to call object bar's frob method but does not access to to frob method.
Object goo does have access to both foo and bar so it can tie it together using delegates. Typically bar and goo are often the same object.
For example a Button class typically doesn't have any access to the class defines a Button_click method.
So now that we have that we can use it for a whole lot things other than just events. Asynch patterns and Linq are two examples.
It seems many of the answers have to do with inline delegates, which in my opinion are easier to make sense of than what I'll call "classic delegates."
Below is my example of how delegates allow a consuming class to change or augment behaviour (by effectively adding "hooks" so a consumer can do things before or after a critical action and/or prevent that behaviour altogether). Notice that all of the decision-making logic is provided from outside the StringSaver class. Now consider that there may be 4 different consumers of this class -- each of them can implement their own Verification and Notification logic, or none, as appropriate.
internal class StringSaver
{
public void Save()
{
if(BeforeSave != null)
{
var shouldProceed = BeforeSave(thingsToSave);
if(!shouldProceed) return;
}
BeforeSave(thingsToSave);
// do the save
if (AfterSave != null) AfterSave();
}
IList<string> thingsToSave;
public void Add(string thing) { thingsToSave.Add(thing); }
public Verification BeforeSave;
public Notification AfterSave;
}
public delegate bool Verification(IEnumerable<string> thingsBeingSaved);
public delegate void Notification();
public class SomeUtility
{
public void SaveSomeStrings(params string[] strings)
{
var saver = new StringSaver
{
BeforeSave = ValidateStrings,
AfterSave = ReportSuccess
};
foreach (var s in strings) saver.Add(s);
saver.Save();
}
bool ValidateStrings(IEnumerable<string> strings)
{
return !strings.Any(s => s.Contains("RESTRICTED"));
}
void ReportSuccess()
{
Console.WriteLine("Saved successfully");
}
}
I guess the point is that the method to which the delegate points is not necessarily in the class exposing the delegate member.
This question already has answers here:
Where do I use delegates? [closed]
(8 answers)
Closed 9 years ago.
I'm relatively new in C#, & I'm wondering when to use Delegates appropriately.
they are widely used in events declaration, but when should I use them in my own code and why are they useful? why not to use something else?
I'm also wondering when I have to use delegates and I have no other alternative.
Thank you for the help!
EDIT: I think I've found a necessary use of Delegates here
A delegate is a reference to a method. Whereas objects can easily be sent as parameters into methods, constructor or whatever, methods are a bit more tricky. But every once in a while you might feel the need to send a method as a parameter to another method, and that's when you'll need delegates.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace DelegateApp {
/// <summary>
/// A class to define a person
/// </summary>
public class Person {
public string Name { get; set; }
public int Age { get; set; }
}
class Program {
//Our delegate
public delegate bool FilterDelegate(Person p);
static void Main(string[] args) {
//Create 4 Person objects
Person p1 = new Person() { Name = "John", Age = 41 };
Person p2 = new Person() { Name = "Jane", Age = 69 };
Person p3 = new Person() { Name = "Jake", Age = 12 };
Person p4 = new Person() { Name = "Jessie", Age = 25 };
//Create a list of Person objects and fill it
List<Person> people = new List<Person>() { p1, p2, p3, p4 };
//Invoke DisplayPeople using appropriate delegate
DisplayPeople("Children:", people, IsChild);
DisplayPeople("Adults:", people, IsAdult);
DisplayPeople("Seniors:", people, IsSenior);
Console.Read();
}
/// <summary>
/// A method to filter out the people you need
/// </summary>
/// <param name="people">A list of people</param>
/// <param name="filter">A filter</param>
/// <returns>A filtered list</returns>
static void DisplayPeople(string title, List<Person> people, FilterDelegate filter) {
Console.WriteLine(title);
foreach (Person p in people) {
if (filter(p)) {
Console.WriteLine("{0}, {1} years old", p.Name, p.Age);
}
}
Console.Write("\n\n");
}
//==========FILTERS===================
static bool IsChild(Person p) {
return p.Age < 18;
}
static bool IsAdult(Person p) {
return p.Age >= 18;
}
static bool IsSenior(Person p) {
return p.Age >= 65;
}
}
}
Output:
Children:
Jake, 12 years old
Adults:
John, 41 years old
Jane, 69 years old
Jessie, 25 years old
Seniors:
Jane, 69 years old
I agree with everything that is said already, just trying to put some other words on it.
A delegate can be seen as a placeholder for a/some method(s).
By defining a delegate, you are saying to the user of your class, "Please feel free to assign any method that matches this signature to the delegate and it will be called each time my delegate is called".
Typical use is of course events. All the OnEventX delegate to the methods the user defines.
Delegates are useful to offer to the user of your objects some ability to customize their behavior.
Most of the time, you can use other ways to achieve the same purpose and I do not believe you can ever be forced to create delegates. It is just the easiest way in some situations to get the thing done.
Say you want to write a procedure to integrate some real-valued function f (x) over some interval [a, b]. Say we want to use the 3-Point Gaussian method to do this (any will do, of course).
Ideally we want some function that looks like:
// 'f' is the integrand we want to integrate over [a, b] with 'n' subintervals.
static double Gauss3(Integrand f, double a, double b, int n) {
double res = 0;
// compute result
// ...
return res;
}
So we can pass in any Integrand, f, and get its definite integral over the closed interval.
Just what type should Integrand be?
Without Delegates
Well, without delegates, we'd need some sort of interface with a single method, say eval declared as follows:
// Interface describing real-valued functions of one variable.
interface Integrand {
double eval(double x);
}
Then we'd need to create a whole bunch of classes implementing this interface, as follows:
// Some function
class MyFunc1 : Integrand {
public double eval(double x) {
return /* some_result */ ;
}
}
// Some other function
class MyFunc2 : Integrand {
public double eval(double x) {
return /* some_result */ ;
}
}
// etc
Then to use them in our Gauss3 method, we need to invoke it as follows:
double res1 = Gauss3(new MyFunc1(), -1, 1, 16);
double res2 = Gauss3(new MyFunc2(), 0, Math.PI, 16);
And Gauss3 needs to do the look like the following:
static double Gauss3(Integrand f, double a, double b, int n) {
// Use the integrand passed in:
f.eval(x);
}
So we need to do all that just to use our arbitrary functions in Guass3.
With Delegates
public delegate double Integrand(double x);
Now we can define some static (or not) functions adhering to that prototype:
class Program {
public delegate double Integrand(double x);
// Define implementations to above delegate
// with similar input and output types
static double MyFunc1(double x) { /* ... */ }
static double MyFunc2(double x) { /* ... */ }
// ... etc ...
public static double Gauss3(Integrand f, ...) {
// Now just call the function naturally, no f.eval() stuff.
double a = f(x);
// ...
}
// Let's use it
static void Main() {
// Just pass the function in naturally (well, its reference).
double res = Gauss3(MyFunc1, a, b, n);
double res = Gauss3(MyFunc2, a, b, n);
}
}
No interfaces, no clunky .eval stuff, no object instantiation, just simple function-pointer like usage, for a simple task.
Of course, delegates are more than just function pointers under the hood, but that's a separate issue (function chaining and events).
Delegates are extremely useful when wanting to declare a block of code that you want to pass around. For example when using a generic retry mechanism.
Pseudo:
function Retry(Delegate func, int numberOfTimes)
try
{
func.Invoke();
}
catch { if(numberOfTimes blabla) func.Invoke(); etc. etc. }
Or when you want to do late evaluation of code blocks, like a function where you have some Transform action, and want to have a BeforeTransform and an AfterTransform action that you can evaluate within your Transform function, without having to know whether the BeginTransform is filled, or what it has to transform.
And of course when creating event handlers. You don't want to evaluate the code now, but only when needed, so you register a delegate that can be invoked when the event occurs.
Delegates Overview
Delegates have the following properties:
Delegates are similar to C++ function pointers, but are type safe.
Delegates allow methods to be passed as parameters.
Delegates can be used to define callback methods.
Delegates can be chained together; for example, multiple methods can be called on a single event.
Methods don't need to match the delegate signature exactly. For more information, see Covariance and Contra variance.
C# version 2.0 introduces the concept of Anonymous Methods, which permit code blocks to be passed as parameters in place of a separately defined method.
I've just go my head around these, and so I'll share an example as you already have descriptions but at the moment one advantage I see is to get around the Circular Reference style warnings where you can't have 2 projects referencing each other.
Let's assume an application downloads an XML, and then saves the XML to a database.
I have 2 projects here which build my solution: FTP and a SaveDatabase.
So, our application starts by looking for any downloads and downloading the file(s) then it calls the SaveDatabase project.
Now, our application needs to notify the FTP site when a file is saved to the database by uploading a file with Meta data (ignore why, it's a request from the owner of the FTP site). The issue is at what point and how? We need a new method called NotifyFtpComplete() but in which of our projects should it be saved too - FTP or SaveDatabase? Logically, the code should live in our FTP project. But, this would mean our NotifyFtpComplete will have to be triggered or, it will have to wait until the save is complete, and then query the database to ensure it is in there. What we need to do is tell our SaveDatabase project to call the NotifyFtpComplete() method direct but we can't; we'd get a ciruclar reference and the NotifyFtpComplete() is a private method. What a shame, this would have worked. Well, it can.
During our application's code, we would have passed parameters between methods, but what if one of those parameters was the NotifyFtpComplete method. Yup, we pass the method, with all of the code inside as well. This would mean we could execute the method at any point, from any project. Well, this is what the delegate is. This means, we can pass the NotifyFtpComplete() method as a parameter to our SaveDatabase() class. At the point it saves, it simply executes the delegate.
See if this crude example helps (pseudo code). We will also assume that the application starts with the Begin() method of the FTP class.
class FTP
{
public void Begin()
{
string filePath = DownloadFileFromFtpAndReturnPathName();
SaveDatabase sd = new SaveDatabase();
sd.Begin(filePath, NotifyFtpComplete());
}
private void NotifyFtpComplete()
{
//Code to send file to FTP site
}
}
class SaveDatabase
{
private void Begin(string filePath, delegateType NotifyJobComplete())
{
SaveToTheDatabase(filePath);
/* InvokeTheDelegate -
* here we can execute the NotifyJobComplete
* method at our preferred moment in the application,
* despite the method being private and belonging
* to a different class.
*/
NotifyJobComplete.Invoke();
}
}
So, with that explained, we can do it for real now with this Console Application using C#
using System;
namespace ConsoleApplication1
{
/* I've made this class private to demonstrate that
* the SaveToDatabase cannot have any knowledge of this Program class.
*/
class Program
{
static void Main(string[] args)
{
//Note, this NotifyDelegate type is defined in the SaveToDatabase project
NotifyDelegate nofityDelegate = new NotifyDelegate(NotifyIfComplete);
SaveToDatabase sd = new SaveToDatabase();
sd.Start(nofityDelegate);
Console.ReadKey();
}
/* this is the method which will be delegated -
* the only thing it has in common with the NofityDelegate
* is that it takes 0 parameters and that it returns void.
* However, it is these 2 which are essential.
* It is really important to notice that it writes
* a variable which, due to no constructor,
* has not yet been called (so _notice is not initialized yet).
*/
private static void NotifyIfComplete()
{
Console.WriteLine(_notice);
}
private static string _notice = "Notified";
}
public class SaveToDatabase
{
public void Start(NotifyDelegate nd)
{
/* I shouldn't write to the console from here,
* just for demonstration purposes
*/
Console.WriteLine("SaveToDatabase Complete");
Console.WriteLine(" ");
nd.Invoke();
}
}
public delegate void NotifyDelegate();
}
I suggest you step through the code and see when _notice is called and when the method (delegate) is called as this, I hope, will make things very clear.
However, lastly, we can make it more useful by changing the delegate type to include a parameter.
using System.Text;
namespace ConsoleApplication1
{
/* I've made this class private to demonstrate that the SaveToDatabase
* cannot have any knowledge of this Program class.
*/
class Program
{
static void Main(string[] args)
{
SaveToDatabase sd = new SaveToDatabase();
/* Please note, that although NotifyIfComplete()
* takes a string parameter, we do not declare it,
* all we want to do is tell C# where the method is
* so it can be referenced later,
* we will pass the parameter later.
*/
var notifyDelegateWithMessage = new NotifyDelegateWithMessage(NotifyIfComplete);
sd.Start(notifyDelegateWithMessage );
Console.ReadKey();
}
private static void NotifyIfComplete(string message)
{
Console.WriteLine(message);
}
}
public class SaveToDatabase
{
public void Start(NotifyDelegateWithMessage nd)
{
/* To simulate a saving fail or success, I'm just going
* to check the current time (well, the seconds) and
* store the value as variable.
*/
string message = string.Empty;
if (DateTime.Now.Second > 30)
message = "Saved";
else
message = "Failed";
//It is at this point we pass the parameter to our method.
nd.Invoke(message);
}
}
public delegate void NotifyDelegateWithMessage(string message);
}
I consider delegates to be Anonymous Interfaces. In many cases you can use them whenever you need an interface with a single method, but you don't want the overhead of defining that interface.
A delegate is a simple class that is used to point to methods with a specific signature, becoming essentially a type-safe function pointer. A delegate's purpose is to facilitate a call back to another method (or methods), after one has been completed, in a structured way.
While it could be possible to create an extensive set of code to perform this functionality, you don’t need too. You can use a delegate.
Creating a delegate is easy to do. Identify the class as a delegate with the "delegate" keyword. Then specify the signature of the type.