Build | |
Coverage | Coveralls SonarQube |
Quality | |
Nuget | |
License |
This is .NET library that aims to provide a faster usage of C# reflection features. Especially the usage of constructor, members accessors (get/set) and attributes.
It provides these features while trying to keep an API as similar as the standard Reflection API (Fully documented and ReSharper compliant).
To see how powerful the library is you can consult some benchmarks there.
The library is highly tested to cover as much as possible real cases, because using Reflection is some kind of core code and must be reliable to build on it.
See the library documentation.
The library is pretty simple to use, it has wrappers of standard Type
, FieldInfo
and PropertyInfo
that are respectively called ImmediateType
, ImmediateField
and ImmediateProperty
.
The get access to fields and properties it is like the standard way, you get access to a Type
and then request its fields and properties.
The entry point of the library is the TypeAccessor
.
See following examples:
ImmediateType type = TypeAccessor.Get(typeof(MySuperType));
// or
ImmediateType type = TypeAccessor.Get<MySuperType>();
Note that there are other access methods that allow to get an ImmediateType
with non public member or by specifying BindingFlags
.
ImmediateType type = TypeAccessor.Get<MySuperType>(includeNonPublicMembers: true);
// or
// Flags allow to get a type with member that fulfill requested flags
ImmediateType type = TypeAccessor.Get<MySuperType>(BindingFlags.Public | BindingFlags.Static);
Note: There is a built-in cache behind the TypeAccessor
.
The ImmediateType
allows to instantiate types via their default constructor if available. This feature is faster than making a traditional call to Activator.CreateInstance(Type)
.
Here is a quick example:
ImmediateType type = TypeAccessor.Get<MySuperType>();
// Create a new instance of MySuperType
object newInstance = type.New();
// You can also use the version that not throws in case of failure
bool succeed = type.TryNew(out object instance, out Exception _);
The ImmediateType
allows to create a copy of a given instance via a copy constructor if available. This feature is faster than making a traditional call to Activator.CreateInstance(Type, Instance)
.
Here is a quick example:
ImmediateType type = TypeAccessor.Get<MySuperType>();
MySuperType instance = new MySuperType
{
TestProperty = 12
};
// Create a copy instance of MySuperType
object newInstance = type.Copy(instance);
// You can also use the version that not throws in case of failure
bool succeed = type.TryCopy(instance, out object newInstance, out Exception _);
Note also that a more easy way of using copy is available as extension directly when manipulating an instance.
MySuperType instance = new MySuperType
{
TestProperty = 12
};
// Create a copy instance of MySuperType
MySuperType newInstance = instance.Copy();
Obviously in such situation you would have directly called the copy constructor of MySuperType
, but we have to keep in mind that it is designed to be use when the instance we manipulate has not been created in such explicit way.
ImmediateType type = TypeAccessor.Get<MySuperType>();
// For fields
ImmediateField field = type.GetField("FieldName");
// or
ImmediateField field = type.Fields["FieldName"];
// There is also type.GetFields()
// For properties
ImmediateProperty property = type.GetProperty("PropertyName");
// or
ImmediateProperty property = type.Properties["PropertyName"];
// There is also type.GetProperties()
// For all members
IEnumerable<ImmediateMember> members = type.Members;
// or
IEnumerable<ImmediateMember> members = type.GetMembers();
// For a member
ImmediateMember member = type.GetMember("MemberName");
// or
ImmediateMember member = type["MemberName"];
When you have type wrapping a field or a property you are able to get or set it like in a standard way.
object instance = new MySuperType();
ImmediateProperty property = type.GetProperty("PropertyName");
// Get
object propertyValue = property.GetValue(instance);
// Set
property.SetValue(instance, "New Value");
To let the user of the library access eventual missing functionalities, each wrapping type from ImmediateReflection gives an access to the equivalent standard structure.
ImmediateProperty property = type.GetProperty("PropertyName");
PropertyInfo propertyInfo = property.PropertyInfo;
Both ImmediateType
, ImmediateField
and ImmediateProperty
inherit from ImmediateMember
which provide an API to check/get attributes that are applied respectively to a type, field or a property.
All methods are accessible in their templated and not templated versions. Following some examples of accessible methods:
ImmediateType type = ...;
bool hasAttribute = type.IsDefined<MyAttribute>();
ImmediateField field = ...;
MyAttribute attribute = field.GetAttribute<MyAttribute>(inherit: true);
ImmediateProperty property = ...;
IEnumerable<Attribute> attributes = property.GetAttributes(typeof(MyAttribute));
IEnumerable<Attribute> attributes = type.GetAllAttributes(inherit: true);
It is also possible to directly retrieve attributes of a given MemberInfo
from the built in cache.
PropertyInfo property = ...;
bool hasAttribute = property.IsDefinedImmediateAttribute<MyAttribute>();
FieldInfo field = ...;
MyAttribute attribute = field.GetImmediateAttribute<MyAttribute>();
By using ImmediateType
API you can manipulate get/set on object via "open" methods, meaning you can specify the instance on which applying the method.
ImmediateReflection also provides an ObjectWrapper
that does the same job as ImmediateType
but on a "closed" way. It means that get/set will be applied only on the wrapped instance.
Following a quick example:
MyClass myObject = new MyClass();
ObjectWrapper wrapper = new ObjectWrapper(myObject);
// Properties/Fields
ImmediateField field = wrapper.GetField("_myField");
ImmediateProperty property = wrapper.GetProperty("MyProperty");
// Get
object propertyValue = wrapper.GetPropertyValue("MyProperty");
// Set
wrapper.SetPropertyValue("MyOtherProperty", 42); // myObject.MyOtherProperty = 42
Note that the wrapper gives access to the wrapped object, its Type
, ImmediateType
and public members.
ImmediateReflection provides an API like standard one for Type
, FieldInfo
and PropertyInfo
, this means get/set for properties use object
both for target and parameter/return type.
But in some cases you know the type owning a property, or better the type of the property too.
To answer these cases ImmediateReflection provides extensions to PropertyInfo
that allow you to create strongly typed delegates for an even faster get/set of properties.
See some of the following examples:
class MyType
{
int MyProperty { get; set; }
string MyStringProperty { get; set; }
}
PropertyInfo myProperty = typeof(MyType).GetProperty(nameof(MyType.MyProperty));
GetterDelegate<MyType, int> getter = myProperty.CreateGetter<MyType, int>();
// Notice that this method can throw if passing invalid types
// There is also a try version
bool succeed = myProperty.TryCreateGetter(out GetterDelegate<MyType, int> getter);
// Then you can use this getter simply like this
MyType myObject = new MyType { MyProperty = 12 };
int value = getter(myObject); // 12
// Note that the same exists for setter
PropertyInfo myStringProperty = typeof(MyType).GetProperty(nameof(MyType.MyStringProperty));
SetterDelegate<MyType, string> setter = myProperty.CreateSetter<MyType, string>();
// Or
bool succeed = myProperty.TryCreateSetter(out SetterDelegate<MyType, string> setter);
// Then you can use this getter simply like this
MyType myObject = new MyType { MyStringProperty = "Init" };
setter(myObject, "New value"); // Sets myObject.MyStringProperty to "New value"
If you only knows the owner type then you can use the alternative version of these delegate helpers that will use object for the property value.
PropertyInfo myProperty = typeof(MyType).GetProperty(nameof(MyType.MyProperty));
GetterDelegate<MyType> getter = myProperty.CreateGetter<MyType>();
// Notice that this method can throw if passing invalid types
// There is also a try version
bool succeed = myProperty.TryCreateGetter(out GetterDelegate<MyType> getter);
// Then you can use this getter simply like this
MyType myObject = new MyType { MyProperty = 12 };
object value = getter(myObject); // 12 wrapped in an object
// Note that the same exists for setter
PropertyInfo myStringProperty = typeof(MyType).GetProperty(nameof(MyType.MyStringProperty));
SetterDelegate<MyType> setter = myProperty.CreateSetter<MyType>();
// Or
bool succeed = myProperty.TryCreateSetter(out SetterDelegate<MyType> setter);
// Then you can use this getter simply like this
MyType myObject = new MyType { MyStringProperty = "Init" };
setter(myObject, "New value"); // Sets myObject.MyStringProperty to "New value"
You can then stores these delegate to boost your reflection get/set over properties.
The library also provides some extensions for standard types to easily get Immediate Reflection types.
Like those:
Type myType = ...;
ImmediateType myImmediateType = myType.GetImmediateType();
Supports Source Link
-
It uses NUnit3 for unit testing (not published).
-
The library code is published annotated with JetBrains annotations.
ImmediateReflection is available on NuGet
PM> Install-Package ImmediateReflection
This project exists thanks to all the people who have contributed to the code base.