What's new in System.Reflection (and friends)
Figured I'd take the opportunity to capitalize on the increased link traffic Brad sent my way, by giving a quick and dirty overview of “What’s new in Reflection”. Illustrated are features I believe are worth their weight in gold - it's a subset of the overall change list. I wrote some of this a little while back to be included in the Whidbey docs, not sure if they’ve made it there yet. As always, things can and normally do change, and taking dependencies on Beta bits is generally a “bad thing(tm)”. Nevertheless, here goes:
Lightweight code gen (LCG)
LCG is probably one of the most interesting features in the late-bound space. I’ve spoken briefly about it here and here. Provides enhanced runtime code generation facilities for emitting static methods at runtime. Less overhead (no need to generate assemblies, modules and types at runtime). GC collection of generated methods which means better resource utilization in long running applications. LCG also has the ability to skip JIT-time visibility checks.
A new feature in Whidbey that allows the user to load an assembly in the “ReflectionOnly” loader context, where no code will be executed. This allows for some loader restrictions to be relaxed, such as the applying of policy. It also allows for reflection over architecture specific assemblies (Reflection over 64bit generated assemblies from a 32bit environment). A example subset of the API:
Assembly asm = Assembly.ReflectionOnlyLoad("assembly.dll");
Type t = Type.ReflectionOnlyGetType("MyType", false, false);
Reflection over MethodBody
This new Whidbey feature allows a user to reflect over a given methods IL stream, its locals, and its exceptions. This is a preliminary API for the power users of reflection. It basically gives the user the ability to parse an IL byte stream. A user is able to reflect on underlying method metadata, and make rational decisions about methods based on their functionality, code paths, exception handling and usage. It also allows a user to realize more than just the method contract and signature. An example subset of the API:
MethodInfo mi = typeof(Foo).GetMethod("Bar");
MethodBody mb = mi.GetMethodBody();
Console.WriteLine("MaxStackSize: " + mb.MaxStackSize);
Console.WriteLine("Local Signature metadata token: " + mb.LocalSignatureMetadataToken);
Console.WriteLine("Byte array length: " + mb.GetILAsByteArray().Length);
Console.WriteLine("Byte array: " + System.Text.Encoding.ASCII.GetString(mb.GetILAsByteArray()));
Token Handle Resolution API’s
My favorite. We’ve got some work to do here, but more on that later. New API’s added to move from Info to metadata token and RuntimeHandle. New API’s added to move from metadata token to RuntimeHandle. User is able to burn in type identity using the Module and metadata token. This has some fairly complex performance and working set benefits that I hope to blog about some other day. There's also the general sense of a better late-bound experience with runtime identity. Also has some interesting “if you were to build a compiler” implications. Example subset of the API:
int fooToken = typeof(Foo).MetadataToken;
RuntimeTypeHandle typeHandle = typeof(Foo).Module.ModuleHandle.ResolveTypeHandle(fooToken);
Reflection and Reflection.Emit support for Generic types
I think this has been well blogged about. We support full reflection and code generation on and of generics types. Various API’s have been added to the XXXInfo range of API’s, along with added Reflection.Emit API’s. I don’t believe the latest community drop supports full Reflection.Emit generics support, but expect that for Beta 2.
Improved Reflection support for Custom Attributes
We can now return a class that has information about a custom attribute, but yet does not execute its constructor! This is part of the whole “ReflectionOnly” story, and generally gives some important semantic benefits.
Touchy subject. I’ll move on before I get in trouble… ;)
Writing a tool (using Reflection of course) to do a diff over Everett vs Whidbey API’s is generally how I work out what we’ve added in other namespaces. It’s pretty simple to do, so I’ll leave it as an exercise to the reader.