Lazy Trick with C#: Delegates, the function pointer

How does one go about calling a function-like variable that dynamically change in behavior? In Java, it’s common to use objects that implements a specific interface to achieve this. The problem is that said code ends up looking very long:

In the code above, by default, the MovingPlatform will move right. You can change this by creating a class that implements Movement, then calling ChangeMovement() with a new instance of Movement similar to the example below:

This causes the platform to start rotating clockwise due to the movement.Move(transform, Time.deltaTime); line in the previous code’s Update() event: if the variable movement happens to be a TranslateMovement like it is initially declared as, it’ll call that class’ Move() function (defined to move right); if movement is a RotateMovement, it’ll call that class’ Move() function.

But that’s a confusing and round-about way of achieving a simple goal. You had to create 4 classes and 1 interface in the above example, which in most workflows, results in 5 different files. Plus, each time you want to add a new way for the platform to move, you’d have to create a new class implementing Movement. Is there a shorter way?

It turns out in C#, there is. Enter delegate, something that allows one to store functions. We can easily shorten the above code into a single class:

Like the code before, this example MovingPlatform will move right by default. Instead of calling the Move() function from an object, however, it’ll call the method TranslateMovement() within MovingPlatform. If you want to change the platform to rotate clockwise instead, you can create a function from anywhere and call ChangeMovement():

Now the movement(transform, Time.deltaTime); line in the Update() event will call RotateMovement() (a private function!) instead of TranslateMovement(). No more interfaces needed; just store functions instead!

How does one use a delegate? When you declare a delegate, you must define what the method’s return type and parameters must be. Take Movement for example: it’s definition (copied below) indicates that it can only store method(s) that returns a void, and has exactly 2 parameters: a Transform and a float.

From there, you can use Movement like a variable type, similar to string, float, and MovingPlatform. For example:

If you want to set the movement variable, first make the function that follows the Movement template.

Then construct a new instance of Movement with that function as the single parameter:

Now you can call movement like a regular function.

delegate also has one more perk that makes it distinct from an interface: you can stack more than one method into a delegate.

It’s worth noting that a delegate cannot store any variables. In that situation, you can just use C#’s interface, which acts just like Java’s interface.

Happy coding!

No Comments

Have something to say? Leave a comment!

We use cookies to ensure that we give you the best experience on our website.