DD.WellWorkover.Cloud/DataTable/PropertyHelper.cs
2021-07-21 15:29:19 +05:00

63 lines
2.5 KiB
C#

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq.Expressions;
using System.Reflection;
namespace DataTable
{
/// <summary>
/// Ускоренный обработчик свойства
/// </summary>
class PropertyHelper
{
delegate void SetterDelegate(object instanse, object[] values);
delegate object GetterDelegate(object instanse);
public string PropertyName { get; }
public string PropertyDesctiption { get; }
public Type PropertyType { get; }
public string Id { get; }
SetterDelegate Setter { get; }
GetterDelegate Getter { get; }
public PropertyHelper(PropertyInfo property)
{
PropertyName = property.Name;
PropertyType = property.PropertyType;
Id = MakeIdentity(property.PropertyType.Name, property.Name);
PropertyDesctiption = GetDescription(property);
var setter = property.SetMethod;
var getter = property.GetMethod;
var instanceExpression = Expression.Parameter(typeof(object), "instance");
var argumentsExpression = Expression.Parameter(typeof(object[]), "arguments");
var argumentExpressions = new List<Expression> { Expression.Convert(Expression.ArrayIndex(argumentsExpression, Expression.Constant(0)), PropertyType) };
var callExpression = Expression.Call(Expression.Convert(instanceExpression, setter.ReflectedType), setter, argumentExpressions);
Setter = Expression.Lambda<SetterDelegate>(callExpression, instanceExpression, argumentsExpression).Compile();
callExpression = Expression.Call(Expression.Convert(instanceExpression, getter.ReflectedType), getter);
Getter = Expression.Lambda<GetterDelegate>(Expression.Convert(callExpression, typeof(object)), instanceExpression).Compile();
}
private string GetDescription(PropertyInfo property)
{
var descriptionAttr = property.GetCustomAttribute<DescriptionAttribute>();
return descriptionAttr?.Description ?? string.Empty;
}
void SetValues(object instance, params object[] values)
=> Setter(instance, values);
public void Set(object instance, object value)
=> SetValues(instance, value);
public object Get(object instance)
=> Getter(instance);
public static string MakeIdentity(string propertyTypeName, string propertyName)
=> $"{propertyTypeName}_{propertyName}".ToLower();
}
}