Wednesday, July 1, 2009

Passing a function as a parameter to another function

You may have wanted to do this. Its actually very important and useful.

We use to pass variables to functions, but passing functions to functions is really a purely object oriented mechanism and really saves you a lot of work.

I'm going to write this example in VB.NET

The Example
Lets say you have a function that somehow loops through all your devices in your house.

You want to create a function that turns off all devices.
Another function that turns on all devices
Perhaps a function that will maintain your devices.

If you want to do that, you'll properly end up duplicating the loop code in all the three functions.


So here is the solution.

Lets first create our mother function, the one which loops through the devices.

Public Sub LoopThroughDevices()
Dim pDevice As IDevice
For Each pDevice In Home.Devices
'---Do Something
Next
End Sub


Now we will create the 3 function, a function that turn a device off, on and maintain

Public Sub Deviceoff(ByVal pDevice As IDevice)
pDevice.off()
End Sub

Public Sub DeviceOn(ByVal pDevice As IDevice)
pDevice.on()
End Sub

Public Sub MaintainDevice(ByVal pDevice As IDevice)
pDevice.Maintain()
End Sub


If we can now pass each function to our LoopThroughDevices function the problem is solved.

We can do this by declaring a Delegate that have the same signature as our 3 functions

Private Delegate Sub DoActiononDevice(ByVal pDevice As IDevice)


Then we will modify our LoopThroughDevices function

'Notice I declared a variable of type DoActiononDevice which is technically a function
Public Sub LoopThroughDevices(ActionFunction as DoActiononDevice)
Dim pDevice As IDevice
For Each pDevice In Home.Devices
'---Call the function
ActionFunction (pDevice)
Next
End Sub



We're done, we just need to call the functions

'To Turn all devices off
LoopThroughDevices (AddressOf Deviceoff)


'To Turn all devices on
LoopThroughDevices (AddressOf Deviceon)


'To Maintain all devices
LoopThroughDevices (AddressOf MaintainDevice)


We used the AddressOf keyword to send-in the function as a variable, it will get a pointer of the address of the function for the LoopThroughDevices to execute it.

Enjoy.