Delegates are used to define what are called callback functions. In other words, you can pass functions around as if they were objects themselves. So, the class that you pass the function to can call the function itself. And, as I mentioned earlier, delegates can be dynamically switched at runtime. So you can define a whole bunch of delegates and then switch out the ones you need with the ones you want. Delegates are created using the delegate keyword, along with a function signature that defines the type of function that the delegate will refer to.
This allows the C# compiler to make delegates type safe. That is, the compiler will check to make sure that the delegate being called has the right number and types of arguments, which helps prevent program bugs. In this case, I'm defining a delegate type, named MyDelegate, that refers to a function that takes an integer and string as arguments and returns an integer as a result. Next, I define a function that actually implements the logic of the delegate. Now, I can define as many of these as I want based upon my program's needs.
But there's no substitute for seeing it in action. Let's jump into some real code and see how all of this works. Here in Visual Studio, open the project named BasicDelegates. Also open the ExampleSnippets file if it's not already open. Once you have the snippets file open, scroll down to the section on basic delegates. This program, like the other examples used in this course, is a bare-bones console application. It just uses the command line to accept input and display output.
These two lines of code right here are just there so that we can pause the program and see the output. Otherwise when we ran it, the command line window would just appear and then disappear when the program completed. Okay. Let's first define our delegate type. Over in the snippets, copy this line of code and paste it into the program.cs file above the definition of the program class. This line defines delegate type, named MyDelegate, that takes two integer arguments and returns a string.
Next, let's implement a couple of functions that will each serve as a version of the delegate. So in the snippets, copy these two functions and paste them inside the top of the program class definition. Notice that each of these functions matches the delegate's signature. Each one takes two integer arguments and returns a string result. The implementations of each function are different.
One adds the numbers while the other one multiplies them. But each result is returned as a string type. Now all that's left to do is create an instance of the delegate and exercise the code. So let's copy these lines right here, and we'll paste those into the main function of the program. All right, let's save. The first line declares a variable f, of type MyDelegate, the type of our delegate from earlier, and assigns it to the first function, func1.
The next line writes an output to the console, and you can see that now we can just call f like any other function. The next line reassigns the value of f to another function, in this case, func2. Then we output some more content to the console by calling f again. This demonstrates you can change the function that the delegate refers to on the fly. Each time we call the function f, it's with the same parameters. But the output will be different.
So let's run our code and see what happens. When we run the program, you can see that the two different numbers are output. Using a delegate, we were able to switch between two different functions while the program was running. In the first case, the output was 30, because 10 plus 20 is 30. In the second case, the output is 200, because 10 times 20 is 200. Now, in this example, I've used static class functions to implement my delegates. But you can also use instance methods of classes as delegates. So let's go back to the code editor.
First let's close this window. And let's copy in the snippets this class definition, MyClass, and let's paste it in the main file above the program class definition. This class defines a method called instanceMethod1. And you can see that it has the same signature as delegate type. It takes two integer arguments and returns a string. Now, to use this function as a delegate, we first have to create an instance of this class and then assign our delegate variable to the instance method.
So back in the snippets, let's copy these few lines and paste them below our previous example, right here. The first line instantiates the class and assigns it to the variable mc. Then we assign the instanceMethod1 function to our delegate variable f. At this point, we can just call the method as we did before. So let's call the function and see the results.
And quickly before we do that, you can see that the function is changed. It adds the two numbers and then multiplies it by arg1 and converts the results to a string. So let's run this. And you can see now that the output of that function is 300. So we have three different result strings, showing that we can create delegates and assign them to both static and instance functions of classes.
Start watching to learn how to adapt this flexible set of programming tools to your own C# programming needs.