How many times have you written code that goes something like this:
if (someValue == SomeEnum.Type1)
Method1("value 1");
else if (someValue == SomeEnum.Type2)
Method2("value 2");
else if (someValue == SomeEnum.Type2)
Method3("value 3");
maybe you used a switch statement to accomplish the same kind of thing.
You can see the pattern there, Method1, Method2 and Method3 all have the same signature and they get executed when the value Type1, Type2 or Type3 is passed. Wouldn't be nice if we could reduce that to a single line?
That's exactly what arrays of methods can do for you, let's see an example, before we can use them we need to set them up
Since all the methods share the same signature it means we can use a delegate to represent all of the methods.
delegate void AddStringDelegate(string someValue);
Now we can declare an array of delegates:
AddStringDelegate[] addStringMethods;
We will use an enumeration to access the items of the array:
enum StringType {
Type1,
Type2,
Type3,
Type4
}
Then we need the actual methods declaration:
void AddStringType1(string someValue) {
OutputText(string.Format("String Type 1: {0}", someValue));
}
void AddStringType2(string someValue) {
OutputText(string.Format("String Type 2: {0}", someValue));
}
void AddStringType3(string someValue) {
OutputText(string.Format("String Type 3: {0}", someValue));
}
finally, on the constructor of our class, we assign the methods to the array to get our array of methods:
addStringMethods = new AddStringDelegate[3];
addStringMethods[(int)StringType.Type1] = new AddStringDelegate(AddStringType1);
addStringMethods[(int)StringType.Type2] = new AddStringDelegate(AddStringType2);
addStringMethods[(int)StringType.Type3] = new AddStringDelegate(AddStringType3);
It's ready to be used, let's see what the implementation looks like:
public void AddString(string someValue, StringType stringType) {
addStringMethods[(int)stringType](someValue);
}
As you can see we can access the required method by converting the enumeration to an int type, our code was just reduced to 1 line; passing the desired enum type gets to our method in one shot
I'll let you decide when you want to use this technique, I wouldn't recommend using it in a small class that gets instantiated and thrown very fast and often, but in some cases it might even be useful there
I think it would be specially useful if we had this kind of pattern inside a singleton class where the class could potentially live a lot longer, you could do all the work to initialize your array of methods and be able to re-use it effectively
Here's the full code for this example, on my next post I'll show you how you could use this technique to implement some kind of factory pattern or what is sometimes referred to as simple factory pattern
class FileGeneratorBase {
delegate void AddStringDelegate(string someValue);
AddStringDelegate[] addStringMethods;
public FileGeneratorBase() {
addStringMethods = new AddStringDelegate[4];
addStringMethods[(int)StringType.Type1] = new AddStringDelegate(AddStringType1);
addStringMethods[(int)StringType.Type2] = new AddStringDelegate(AddStringType2);
addStringMethods[(int)StringType.Type3] = new AddStringDelegate(AddStringType3);
addStringMethods[(int)StringType.Type4] = new AddStringDelegate(AddStringType4);
}
public void AddString(string someValue, StringType stringType) {
addStringMethods[(int)stringType](someValue);
}
void AddStringType1(string someValue) {
OutputText(string.Format("String Type 1: {0}", someValue));
}
void AddStringType2(string someValue) {
OutputText(string.Format("String Type 2: {0}", someValue));
}
void AddStringType3(string someValue) {
OutputText(string.Format("String Type 3: {0}", someValue));
}
void AddStringType4(string someValue) {
OutputText(string.Format("String Type 4: {0}", someValue));
}
void OutputText(string someValue) {
Console.WriteLine(someValue);
}
}
class Program {
static void Main(string[] args) {
FileGeneratorBase fg = new FileGeneratorBase();
fg.AddString("some value", StringType.Type1);
fg.AddString("some other value", StringType.Type2);
fg.AddString("one last value", StringType.Type3);
fg.AddString("testing out of bounds", StringType.Type4);
Console.ReadLine();
}
}
updated: To initialize the array using the same enum instead of hardcoded values of 0..4