This library has been deprecated and will no longer receive updates.
RockLib has been a cornerstone of our open source efforts here at Rocket Mortgage, and it's played a significant role in our journey to drive innovation and collaboration within our organization and the open source community. It's been amazing to witness the collective creativity and hard work that you all have poured into this project.
However, as technology relentlessly evolves, so must we. The decision to deprecate this library is rooted in our commitment to staying at the cutting edge of technological advancements. While this chapter is ending, it opens the door to exciting new opportunities on the horizon.
We want to express our heartfelt thanks to all the contributors and users who have been a part of this incredible journey. Your contributions, feedback, and enthusiasm have been invaluable, and we are genuinely grateful for your dedication. 🚀
Extension methods to improve reflection performance.
This library supports the following targets:
- .NET 6
- .NET Core 3.1
- .NET Framework 4.8
RockLib.Reflection.Optimized has extension methods for two types: System.Reflection.PropertyInfo and System.Reflection.FieldInfo. These extension methods create functions at runtime that get or set the specified property or field.
The following code snippet demonstrates usage of the CreateGetter and CreateSetter extension methods for PropertyInfo (usage for FieldInfo is identical):
using System.Reflection;
using RockLib.Reflection.Optimized;
public class Foo
{
public int Bar { get; set; }
}
void Main()
{
PropertyInfo property = typeof(Foo).GetProperty("Bar");
Action<object, object> setBar = property.CreateSetter();
Func<object, object> getBar = property.CreateGetter();
Foo foo = new Foo();
setBar(foo, 123); // Sets the value of the Bar property
int bar = getBar(foo); // Gets the value of the Bar property
}The CreateGetter and CreateSetter extension methods for PropertyInfo and FieldInfo each have three overloads, allowing the parameters of the resulting delegates to be customized.
| Overload | Return Type |
|---|---|
CreateGetter |
Func<object, object> |
CreateSetter |
Action<object, object> |
CreateGetter<TPropertyType> |
Func<object, TPropertyType> |
CreateSetter<TPropertyType> |
Action<object, TPropertyType> |
CreateGetter<TDeclaringType, TPropertyType> |
Func<TDeclaringType, TPropertyType> |
CreateSetter<TDeclaringType, TPropertyType> |
Action<TDeclaringType, TPropertyType> |
If a PropertyInfo or FieldInfo represents a static property or field, then the first parameter of the functions returned by the CreateGetter and CreateSetter methods are ignored. When invokine functions that access static properties or fields, the caller can safely pass null for the first parameter.
If it is known that a PropertyInfo or FieldInfo is static, then the CreateStaticGetter and CreateStaticSetter extension methods can be used, as in the following FieldInfo example (usage for PropertyInfo is identical):
using System.Reflection;
using RockLib.Reflection.Optimized;
public static class Foo
{
public static int Bar;
}
void Main()
{
FieldInfo field = typeof(Foo).GetField("Bar");
Action<object> setBar = field.CreateStaticSetter();
Func<object> getBar = field.CreateStaticGetter();
Foo foo = new Foo();
setBar(123); // Sets the value of the Foo.Bar property
int bar = getBar(); // Gets the value of the Foo.Bar property
}Similar to their non-static counterpoints, the CreateStaticGetter and CreateStaticSetter extension methods for PropertyInfo and FieldInfo each have two overloads, allowing the parameters of the resulting delegates to be customized.
| Overload | Return Type |
|---|---|
CreateStaticGetter |
Func<object> |
CreateStaticSetter |
Action<object> |
CreateStaticGetter<TPropertyType> |
Func<TPropertyType> |
CreateStaticSetter<TPropertyType> |
Action<TPropertyType> |
RockLib.Reflection.Optimized also contains an Undecorate extension method. This extension method checks to see if an object implementing an interface is a decorator for that interface, and if it is, unwraps it. An object is considered a decorator if it has an instance field of the same type as the interface it implements. To unwrap a decorator object, the value of its interface instance field is used instead. The following example demonstrates usage of the Undecorate extension method:
void Main()
{
IFoo foo = new FooDecorator(new AnotherFooDecorator { Foo = new MutableFoo() });
if (foo.Undecorate() is MutableFoo mutableFoo)
mutableFoo.Bar = 123;
}
public interface IFoo
{
int Bar { get; }
}
public class MutableFoo : IFoo
{
public int Bar { get; set; }
}
public class FooDecorator : IFoo
{
private readonly IFoo _foo;
public FooDecorator(IFoo foo) => _foo = foo;
public int Bar => _foo.Bar;
}
public class AnotherFooDecorator : IFoo
{
public IFoo Foo { get; set; }
public int Bar => Foo?.Bar ?? 0;
}