One of the things that makes .NET such a powerful platform is the ability to interrogate language constructs. The “reflection” subsystem is available in the base class libraries. This means that you can find out anything about anything.
If you have a custom class, you easily can get the runtime to show you what’s inside of it. If you have a data object to store in a database, you can easily find out what field types you need and much more.
Everything Starts with a ‘Type’
The key to reading most of the information is to use the .NET ‘Type’ class to find out information about the type you want to work with.
Start a console mode project, and then make sure you have the following in ‘Program.cs’:
using System; namespace ReflectionRefresher { class Program { static void Main() { Type myType = typeof (double); } } }
Place a break point on the ‘Type’ line and press F5. Once you hit your break point, press F10 once and examine your local’s inspector. You should see something that looks similar to this:
Figure 1: Type information about the built-in double type
You’ll see pretty much immediately that you can find out which .NET library double is defined in, what its full name is, what its registered GUID is, and lots of other meta information.
What if you don’t know the name of your type ahead of time? Change your main code so it looks as follows:
using System; namespace ReflectionRefresher { class Program { static void Main() { var myNumber = 100; Type myType = myNumber.GetType(); } } }
Put a break point on the ‘var’ line. Again, press F5 to run, and F10 twice to step over the two code lines.
Once again, expand the local’s for your ‘myType’ variable:
Figure 2: Type properties for an unknown type
As you can see, the compiler has picked Int32 as the variable type. If you try this a few more times but give the number a decimal part, or enclose it in quote marks, you’ll see that the compiler will choose what it believes is the best type to represent the data you’re working with.
Moving on from here, we can easily use the methods available in the type class to get lists of properties, methods, fields, and many other things. Change your main routine in ‘Program.cs’ so that it looks like the following:
using System; namespace ReflectionRefresher { class Program { static void Main() { Int32 myNumber = 100; Type myType = myNumber.GetType(); Console.WriteLine("Int32 Info:\n"); Console.WriteLine("Properties"); if(myType.GetProperties().Length > 0) { foreach (var propertyInfo in myType.GetProperties()) { console.WriteLine("Property Name: {0}", propertyInfo.Name); } } else { Console.WriteLine("Type has no properties"); } Console.WriteLine(); Console.WriteLine("Methods"); if (myType.GetMethods().Length > 0) { foreach (var methodInfo in myType.GetMethods()) { Console.WriteLine("Property Name: {0}", methodInfo.Name); } } else { Console.WriteLine("Type has no methods"); } Console.WriteLine(); Console.WriteLine("Fields"); if (myType.GetFields().Length > 0) { foreach (var fieldInfo in myType.GetFields()) { Console.WriteLine("Field Name: {0}", fieldInfo.Name); } } else { Console.WriteLine("Type has no fields"); } Console.WriteLine(); } } }
If you run this, you should see something like the following:
Figure 3: Properties, Methods, and Fields available in the Int32 data type
As you can see, in a very few lines of code we know exactly what the Int32 class gives us and where it’s declared.
I’m sure at this point you can start to think of lots of ways you can use this. For example, you can generate SQL statements automatically for a database, directly from a .NET class.
Got a sticky problem with .NET that’s leaving you… stuck? Come hunt me down on Twitter as @shawty_ds. You never know; I might just do my next post on your topic.