public class PropertyAccess
{
public const BindingFlags PropertyBinding = BindingFlags.Public | BindingFlags.Instance | BindingFlags.GetProperty
//| BindingFlags.DeclaredOnly
;
public readonly Func<object, object> GetValue;
public readonly Action<object, object> SetValue;
protected PropertyAccess(string name, bool nullable, PropertyInfo property)
{
// target: (object)((({TargetType})instance).{Property})
// preparing parameter, object type
ParameterExpression instance = Expression.Parameter(typeof(object), "instance");
// ({TargetType})instance
UnaryExpression instanceCast = Expression.Convert(instance, property.ReflectedType);
if (property.CanRead)
{
// (({TargetType})instance).{Property}
MemberExpression propertyAccess = Expression.Property(instanceCast, property);
// (object)((({TargetType})instance).{Property})
UnaryExpression castPropertyValue = Expression.Convert(propertyAccess, typeof(object));
// Lambda expression
GetValue = Expression.Lambda<Func<object, object>>(castPropertyValue, instance).Compile();
}
if (property.CanWrite)
{
ParameterExpression propertyValue = Expression.Parameter(typeof(object), "value");
UnaryExpression propertyValueCast = Expression.Convert(propertyValue, property.PropertyType);
MethodCallExpression callPropertyValue = Expression.Call(instanceCast, property.GetSetMethod(), propertyValueCast);
SetValue = Expression.Lambda<Action<object, object>>(callPropertyValue, instance, propertyValue).Compile();
}
}
public object ChangeType(object value)
{
return Convert.ChangeType(value, Nullable.GetUnderlyingType(base.EntityProperty.PropertyType) ?? base.EntityProperty.PropertyType);
}
}