Anyone who has played with .NET long enough will tell you that
Reflection is a really cool feature. Essentially, reflection
enables the developer to query the type system (CLT - Common Language
Type system), dynamically invoke methods, and dynamically create types
at runtime, using meta-data stored in the .NET assemblies. The reflection
API is built into the framework. The only snag with using
reflection is paying the performance cost.
This post is not about dodging the performance pitfalls with
performance -
Joel Pobar, a program manager on the CLR (Common Language
Runtime) team at Microsoft, has written a great
article,
which is
extensive and covers the topic of reflection performance.
Instead, I would like to take this opportunity to mention Lightweight
Code Generation (LCG) in version 2.0 of the .NET Framework.
What is LCG?
LCG is all about generating code on the fly at runtime, which can be
executed. A good use for LCG is avoiding the performance bloat
associated with method invocation in reflection. How many times
have you seen the following code?
The above example code gets a Type object (t) for the Console class,
and then invokes the WriteLine method, using the InvokeMember
method. Of course, this example is not a good representation of a
real world scenario, because it is unlikely that a developer would call
the static WriteLine method of the console class in this way.
However, imagine that the type (t) was obtained dynamically via
reflection, perhaps as a result of querying custom attributes of a
property or class (GetCustomAttributes). The developer may intend
a method call on the type (t) during runtime without knowing the class
type at compile time. Regardless of how a Type object (t) is
obtained, calling InvokeMember is bad for performance (see Joel's
article for reasons why).
A better approach to the above example would be to obtain a MethodInfo
instance for the dynamically called WriteLine method and then call the
MethodInfo.Invoke method. This approach is faster than using
Type.InvokeMember, but still not that fast.
Version 2.0 of the Framework introduces LCGs, which is a half way
compromise between early bound invocation (invocation determined at
compile time) and late bound invocation (invocation determined at
runtime). LCGs are about creating IL (Intermediate Language)
code, similar to what the compiler would generate as early bound
invocation, at runtime, and then calling the generated IL code from
your application infrastructure. Joel touches on LCGs in his
article, and explains them further on his
blog, the
MSDN is also a good
resource for knowledge on this subject.
Below is a helper class (written with the help of examples from Joel on
CodeProject), which contains two public methods. The Create
method is a replacement for MethodInfo.Invoke, which dynamically
invokes a method on a class (static) or object (non-static) using an
LCG. The second method - CreateInstance - will create an instance
object from a Type class by using emitted IL in an LCG. Both of
these helper methods are faster performing than the aforementioned
Type.InvokeMember and MemberInfo.Invoke API methods (perhaps I'll post
evidence of this later).
The above helper methods can be called using the example code below: