I'm a dumbass (and other news)
So yesterday I got all mad that in C# you can't create a delegate by passing a MethodInfo to its constructor, and I started trying to figure out how I might just write some raw IL to manually call the constructor that way for me. Thank goodness Stefan Holdermans reminded me that you don't have to use "new" to create delegates - System.Delegate::CreateDelegate(Type t, string method) does exactly what I wanted. *blush!*
I like the code I created with it. I was writing a class that acts like an aggretator - it maps a bunch of delegates to labels, and exposes an Invoke(string label) method to allow the outside world to call. The class is extensible - there are ways for the outside world to map in their own functions - but the class itself provides a number of default implementations mapped to default labels. After Stefan reminded me about Delegate.CreateDelegate I was able to make a pretty elegant constructor:
public Aggregator() { foreach(MethodInfo m in this.GetType().GetMethods(...)) { if(m.Name.IndexOf("Routine_") != -1) { Delegate d = Delegate.CreateDelegate(typeof(Subroutine), this, m.Name); string label = m.Name.Substring(8); Subroutines[label] = d; } } }
Now I can just add new functions to my class that begin with Routine_ and they will automatically get picked up for inclusion in the hashtable. This is sooo much nicer than it would have been in C++, where it probably would have looked like:
Aggregator() { BEGIN_SUBROUTINE_MAP(Subroutines) SUBROUTINE_ENTRY(Routine_1) SUBROUTINE_ENTRY(Routine_2) SUBROUTINE_ENTRY(Routine_3) ...etc, etc... END_SUBROUTINE_MAP() }
Come to think of it I'm hardly the first to use this trick, don't WinForms/WebForms do basically the same thing to enable derived classes to handle events by just creating a method with a specially formatted name?
5:38:07 AM
|