Skip to content

.NET library that aims to provide faster usage of C# reflection features. Especially the usage of constructor and members accessors (get/set). It also provides an ObjectWrapper object allowing to use Reflection in a faster way. And finally it offers the possibility to create strongly typed delegates.

License

Notifications You must be signed in to change notification settings

KeRNeLith/ImmediateReflection

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Build AppVeyor Build Status
Coverage Coveralls Coverage Status SonarQube SonarCloud Coverage
Quality Quality Gate
Nuget Nuget status
License GitHub license

ImmediateReflection

What is ImmediateReflection?

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.

Getting started

See the library documentation.

Getting a type

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.

Instantiate a type

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 _);

Copy an instance

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.

Getting a field or a property

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;

Getting attributes

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>();

Object wrapper

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.

Creating typed delegate (Open delegate)

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.

Extensions

The library also provides some extensions for standard types to easily get Immediate Reflection types.

Like those:

Type myType = ...;

ImmediateType myImmediateType = myType.GetImmediateType();

Targets

  • .NET Standard
  • .NET Core
  • .NET Framework

Supports Source Link

Notes

  • It uses NUnit3 for unit testing (not published).

  • The library code is published annotated with JetBrains annotations.


Installation

ImmediateReflection is available on NuGet

PM> Install-Package ImmediateReflection

Maintainer(s)

Contributor(s)

This project exists thanks to all the people who have contributed to the code base.


About

.NET library that aims to provide faster usage of C# reflection features. Especially the usage of constructor and members accessors (get/set). It also provides an ObjectWrapper object allowing to use Reflection in a faster way. And finally it offers the possibility to create strongly typed delegates.

Topics

Resources

License

Code of conduct

Stars

Watchers

Forks

Sponsor this project

 

Packages