I've not used delegates before now and I'm trying to figure them out following a tutorial in my book.
So far I've picked up the that a delegate can be used with methods of a class that return the same type object and are overloaded with the same objects as the delegate making the call (please correct me if I'm wrong).
In the tutorial I'm working on, the following code is added to a Car Class:
public delegate void CarEngineHandler(string msgForCaller);
private CarEngineHandler listOfHandlers;
public void RegisterWithCarEngine(CarEngineHandler methodToCall)
{
listOfHandlers = methodToCall;
}
In Main of the console app the following code is called:
static void Main(string[] args)
{
Car c1 = new Car("Slugbug", 100, 10);
c1.RegisterWithCarEngine(new Car.CarEngineHandler(OnCarEngineEvent));
Console.WriteLine("**** Speeding Up ******");
for (int i = 0; i < 6; i++)
c1.Accelerate(20);
Console.ReadLine();
}
public static void OnCarEngineEvent(string msg)
{
Console.WriteLine("\n***** Message From Car Object *****");
Console.WriteLine("=> {0}", msg);
Console.WriteLine("*************************************\n");
}
And here is the Accelerate method:
public void Accelerate(int delta)
{
if (carIsDead)
{
if (listOfHandlers != null)
listOfHandlers("Sorry, this car is dead...");
}
else
{
CurrentSpeed += delta;
if (10 == (MaxSpeed - CurrentSpeed) && listOfHandlers != null)
{
listOfHandlers("Careful buddy! Gunna Blow!");
}
}
if (CurrentSpeed >= MaxSpeed)
carIsDead = true;
else
Console.WriteLine("CurrentSpeed = {0}", CurrentSpeed);
}
I'm puzzled as to how exactly listofHandlers is actually working here? I know this isn't a fault with any code, but I'd like understand more about how delegates actually work? Checking that listofHandlers is null is throwing me off...
In C# you can make a pointer to a method. Such a pointer is called a Delegate. A delegate is just a normal object with methods. It can only point to methods that have matching parameter types and a matching return type.
delegate string MyHandler(int value1, string value2);
Defines a delegate type that can point to a method that has (
int,string) as the parameter types and returns astring.
You can store such a delegate (pointer to a method) in a field.
MyHandler myhandler;
This delegate is just an object, so like any object it can be null.
Given a method:
string X(int v1, string v2) { /* ... */ }
You can create a new delegate that points to that method:
myHandler = new MyHandler(X);
Or, thanks to syntactic sugar, you can use this shorter syntax:
myHandler = X;
At any point later, you can invoke the method pointed to by the delegate.
int i = 10;
string s = String.Empty;
string result = myHandler.Invoke(i, s);
Or, again thanks to syntactic sugar:
int i = 10;
string s = String.Empty;
string result = myHandler(i, s);
Of course, myHandler can be null, so you'll need to check that first or you'll get a NullReferenceException. After all, you can't call instance methods on null.
myHandler = null;
myHandler.Invoke(10, "");
So, they check for that:
string result;
if (myHandler != null)
result = myHandler(i, s);
Or almost equivalent, in C# 6: (Note that result will be null when myHandler is null.)
string result = myHandler?.Invoke(i, s);
If you want to use the same code to call different methods, you can pass a delegate that points to the method to be called as a parameter or field in an object. This is how events are implemented in .NET, and why LINQ works.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With