Introduction
Reflection API is very powerfull. It provide a way to analyse code at runtime and offer a lots of features to increase productivity by suppress a lot of boilerplate code. In another hand, Reflection API can introduce a lot of exceptions at runtime and can make an application very difficult to evolve.
Common usage of Reflection
Reflection provide metadatas to describe your source code :
- System.Type
- System.Reflection.Assembly
- System.Reflection.MemberInfo
- System.Reflection.FieldInfo
- System.Reflection.MethodBase
- System.Reflection.ConstructorInfo
- System.Reflection.MethodInfo
- System.Reflection.PropertyInfo
- System.Reflection.ParameterInfo
- ...
I will not describe all these metadata because you can find full documentation in the MSDN :
https://msdn.microsoft.com/en-us/library/system.reflection(v=vs.110).aspx
Example of reflection usage :
- typeof keyword allow you to get System.Type object containing all you needs to instrospect a type.
Type type = typeof(object);
- from a type you can get members
Type type = typeof(object);
MethodInfo method = typeof(object).GetMethod("GetHashCode");
ConstructorInfo constructor = typeof(object).GetConstructor(Type.EmptyTypes);
Why is it an issue to use it like this?
The typeof keyword is not bad because it is checked at compile time, but GetMethod, GetField, GetProperty & GetConstructor can introduce runtime error and make program harder to envolve. Indeed, if you change a method name or field name, your reflection will failed event if it work before. It means that you have to be carefully in each reflection usage when program change.
What can I do to avoid theses issues?
Just avoid Reflection if you can. Indeed, if the cost of program without reflection is not too heavy to handle, do it. Fortunately, generics can help a lot to do it. But in some case it is really more productive to introduce reflection into program. That's why Puresharp Reflection API .NET 4.0+ can help you to make your reflection usafe safer.
Puresharp Reflection API
Puresharp Reflection API .NET 4.0+ is a set of classes allowing safer Reflection usage using linq & lambda expressions. It provide API to get static and instance metadatas and is materialized as nuget package :
https://www.nuget.org/packages/Puresharp.Reflection
The principle is simple, you just have to express your metadata using lambda expression compatible for linq expression.
Use cases : each case compare Standard Reflection vs Puresharp Reflection
- fast access to type by using generic type cache
Type type = typeof(object);
Type type = Metadata<object>.Type;
- get constructor of an type
ConstructorInfo constructor = typeof(Uri).GetConstructor(new Type[] { typeof(string) });
ConstructorInfo constructor = Metadata.Constructor(() => new Uri(Argument<string>.Value));
FieldInfo field = typeof(Uri).GetField("SchemeDelimiter");
FieldInfo field = Metadata.Field(() => Uri.SchemeDelimiter);
MethodInfo method = typeof(object).GetMethod("ReferenceEquals", new Type[] { typeof(object), typeof(object) });
MethodInfo method = Metadata.Method(() => object.ReferenceEquals(Argument<object>.Value, Argument<object>.Value));
PropertyInfo property = typeof(AppDomain).GetProperty("CurrentDomain");
PropertyInfo property = Metadata.Property(() => AppDomain.CurrentDomain);
public class MyClass
{
public int MyField;
}
FieldInfo field = typeof(MyClass).GetField("MyField");
FieldInfo field = Metadata<MyClass>.Field(myClass => myClass.MyField);
MethodInfo method = typeof(DateTime).GetMethod("Add", new Type[] { typeof(TimeSpan) });
MethodInfo method = Metadata<DateTime>.Method(datetime => datetime.Add(Argument<TimeSpan>.Value));
PropertyInfo property = typeof(DateTime).GetProperty("Second");
PropertyInfo property = Metadata<DateTime>.Property(datetime => datetime.Second);
NOTE : instance resolution required a parameter expression to express an instance member and generic class Argument is a class helper to use as a token to discriminate the exact member.
Conclusion
Even if reflection is a cool thing, be careful when you use it. Fortunately, Puresharp Reflection API .NET 4.0+ provide a safer way to do it by only reference a nuget package from nuget.org. This project is open source and under MIT licence that allow you to use it without any restrictions.