Working with Delegates in C# - ' Dynamic Delegate Invocation ' (
Page 3 of 6 )
Dynamic Delegate Invocation
Sometimes you don't know what method you want to execute until runtime. One option is to use a delegate, which allows you to separate implementation of method logic from the controlling application logic, as shown in Listing 2.
Listing 2. DynamicDelegates.cs
using System;
// 1. Define delegate.
public delegate double UnitConversion(double from);
class DynamicDelegates
{
//
// 2. Define handler methods.
//
public double FeetToInches(double feet)
{
return feet * 12;
}
public double YardsToInches(double yards)
{
return yards * 36;
}
// Factory method for returning delegate
public UnitConversion GetConversionMethod(string conversionType)
{
UnitConversion conversion;
switch (conversionType)
{
case "1":
conversion = new UnitConversion(FeetToInches);
break;
case "2":
conversion = new UnitConversion(YardsToInches);
break;
default:
throw new ArgumentException("Unrecognized conversion type: " + conversionType, conversionType);
}
return conversion;
}
// show menu and return units to convert and type of conversion
public void GetUserInput(out double units, out string conversionType)
{
Console.WriteLine("Units Converter");
Console.WriteLine("------------------------\n");
Console.WriteLine("1 - Feet to Inches");
Console.WriteLine("2 - Yards to Inches");
Console.Write("\nPlease select conversion option (1 or 2): ");
conversionType = Console.ReadLine();
Console.Write("\n\nPlease enter units: ");
units = Double.Parse(Console.ReadLine());
}
static void Main()
{
DynamicDelegates dels = new DynamicDelegates();
double units;
string conversionType;
dels.GetUserInput(out units, out conversionType);
// 3. get delegate instance via factory method.
UnitConversion doConversion = dels.GetConversionMethod(conversionType);
// 4. Use delegate just like a method.
double inches = doConversion(units);
Console.WriteLine("\n{0} Units = {1} Inches.\n", units, inches);
Console.ReadLine();
}
}
ADVERTISEMENT
Listing 2 is an evolution of Listing 1 that allows the user to implement multiple conversions. In this case, it is only two conversions, but you could expand this example to many more methods. The way it is implemented, using a delegate, allows the algorithm in the Main method to remain untouched while new conversions are added to the application.
One difference between Listing 1 and Listing 2 is that Listing 1 used a static method for the handler method, and the handler methods in Listing 2 are instance methods. Delegates will accept either instance or static method handlers with no problem. When invoked via a referring delegate, static methods operate on their type; instance methods operate on their associated instance.
This example uses a factory method, GetConversionMethod, to return a delegate referring to a method matching the user's input. In Main, the delegate is received and invoked. It is certainly possible that parameters could have been passed to a special method that performed the invocations and returned — that's a design decision you could make. However, now you have the ability to do what ever you want with the delegate, such as invoking it right away, passing it to another method, or saving it for later.
Manipulating Society through Technology
Jeremy Bailenson, Director of the Virtual Human Interaction Lab at Stanford University, talks about virtual reality, avatars, Moore's law, how real world behaviors influence online reality, and societal manipulation through technology! >> Play video >> Read article >> See all videos