123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199 |
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Linq.Expressions;
- using System.Reflection;
- using System.Text;
- using System.Threading.Tasks;
- namespace EasyDevCore.Common
- {
- /// <summary>
- ///
- /// </summary>
- public static class ExpressionHelper
- {
- /// <summary>
- /// Gets the property.
- /// </summary>
- /// <typeparam name="TEntity">The type of the entity.</typeparam>
- /// <typeparam name="TProperty">The type of the property.</typeparam>
- /// <param name="expression">The expression.</param>
- /// <returns></returns>
- /// <exception cref="InvalidOperationException"></exception>
- public static PropertyInfo GetProperty<TEntity, TProperty>(Expression<Func<TEntity, TProperty>> expression)
- {
- var member = GetMemberExpression(expression).Member;
- var property = member as PropertyInfo;
- if (property == null)
- {
- throw new InvalidOperationException(string.Format("Member with Name '{0}' is not a property.", member.Name));
- }
- return property;
- }
- /// <summary>
- /// Gets the member expression.
- /// </summary>
- /// <typeparam name="TEntity">The type of the entity.</typeparam>
- /// <typeparam name="TProperty">The type of the property.</typeparam>
- /// <param name="expression">The expression.</param>
- /// <returns></returns>
- /// <exception cref="ArgumentException">Not a member access - expression</exception>
- private static MemberExpression GetMemberExpression<TEntity, TProperty>(Expression<Func<TEntity, TProperty>> expression)
- {
- MemberExpression memberExpression = null;
- if (expression.Body.NodeType == ExpressionType.Convert)
- {
- var body = (UnaryExpression)expression.Body;
- memberExpression = body.Operand as MemberExpression;
- }
- else if (expression.Body.NodeType == ExpressionType.MemberAccess)
- {
- memberExpression = expression.Body as MemberExpression;
- }
- if (memberExpression == null)
- {
- throw new ArgumentException("Not a member access", "expression");
- }
- return memberExpression;
- }
- /// <summary>
- /// Creates the setter.
- /// </summary>
- /// <typeparam name="TEntity">The type of the entity.</typeparam>
- /// <typeparam name="TProperty">The type of the property.</typeparam>
- /// <param name="property">The property.</param>
- /// <returns></returns>
- public static Action<TEntity, TProperty> CreateSetter<TEntity, TProperty>(Expression<Func<TEntity, TProperty>> property)
- {
- PropertyInfo propertyInfo = ExpressionHelper.GetProperty(property);
- ParameterExpression instance = Expression.Parameter(typeof(TEntity), "instance");
- ParameterExpression parameter = Expression.Parameter(typeof(TProperty), "param");
- var body = Expression.Call(instance, propertyInfo.GetSetMethod(), parameter);
- var parameters = new ParameterExpression[] { instance, parameter };
- return Expression.Lambda<Action<TEntity, TProperty>>(body, parameters).Compile();
- }
- /// <summary>
- /// Creates the getter.
- /// </summary>
- /// <typeparam name="TEntity">The type of the entity.</typeparam>
- /// <typeparam name="TProperty">The type of the property.</typeparam>
- /// <param name="property">The property.</param>
- /// <returns></returns>
- public static Func<TEntity, TProperty> CreateGetter<TEntity, TProperty>(Expression<Func<TEntity, TProperty>> property)
- {
- PropertyInfo propertyInfo = ExpressionHelper.GetProperty(property);
- ParameterExpression instance = Expression.Parameter(typeof(TEntity), "instance");
- var body = Expression.Call(instance, propertyInfo.GetGetMethod());
- var parameters = new ParameterExpression[] { instance };
- return Expression.Lambda<Func<TEntity, TProperty>>(body, parameters).Compile();
- }
- /// <summary>
- /// Creates the default constructor.
- /// </summary>
- /// <typeparam name="TEntity">The type of the entity.</typeparam>
- /// <returns></returns>
- public static Func<TEntity> CreateDefaultConstructor<TEntity>()
- {
- var body = Expression.New(typeof(TEntity));
- var lambda = Expression.Lambda<Func<TEntity>>(body);
- return lambda.Compile();
- }
- /// <summary>
- /// Gets the property getter.
- /// </summary>
- /// <typeparam name="TObject">The type of the object.</typeparam>
- /// <typeparam name="TProperty">The type of the property.</typeparam>
- /// <param name="propertyName">Name of the property.</param>
- /// <returns></returns>
- public static Func<TObject, TProperty> GetPropGetter<TObject, TProperty>(string propertyName)
- {
- ParameterExpression paramExpression = Expression.Parameter(typeof(TObject), "value");
- Expression propertyGetterExpression = Expression.Property(paramExpression, propertyName);
- Func<TObject, TProperty> result =
- Expression.Lambda<Func<TObject, TProperty>>(propertyGetterExpression, paramExpression).Compile();
- return result;
- }
- /// <summary>
- /// Gets the property setter.
- /// </summary>
- /// <typeparam name="TObject">The type of the object.</typeparam>
- /// <typeparam name="TProperty">The type of the property.</typeparam>
- /// <param name="propertyName">Name of the property.</param>
- /// <returns></returns>
- public static Action<TObject, TProperty> GetPropSetter<TObject, TProperty>(string propertyName)
- {
- ParameterExpression paramExpression = Expression.Parameter(typeof(TObject));
- ParameterExpression paramExpression2 = Expression.Parameter(typeof(TProperty), propertyName);
- MemberExpression propertyGetterExpression = Expression.Property(paramExpression, propertyName);
- Action<TObject, TProperty> result = Expression.Lambda<Action<TObject, TProperty>>
- (
- Expression.Assign(propertyGetterExpression, paramExpression2), paramExpression, paramExpression2
- ).Compile();
- return result;
- }
- /// <summary>
- /// Gets the value getter.
- /// var getter = property.GetValueGetter<ReflectedType>();
- /// </summary>
- /// <typeparam name="T"></typeparam>
- /// <param name="propertyInfo">The property information.</param>
- /// <returns></returns>
- /// <exception cref="ArgumentException"></exception>
- public static Func<T, object> GetValueGetter<T>(this PropertyInfo propertyInfo)
- {
- if (typeof(T) != propertyInfo.DeclaringType)
- {
- throw new ArgumentException();
- }
- var instance = Expression.Parameter(propertyInfo.DeclaringType, "i");
- var property = Expression.Property(instance, propertyInfo);
- var convert = Expression.TypeAs(property, typeof(object));
- return (Func<T, object>)Expression.Lambda(convert, instance).Compile();
- }
- /// <summary>
- /// Gets the value setter.
- /// var setter = property.GetValueSetter<ReflectedType>();
- /// </summary>
- /// <typeparam name="T"></typeparam>
- /// <param name="propertyInfo">The property information.</param>
- /// <returns></returns>
- /// <exception cref="ArgumentException"></exception>
- public static Action<T, object> GetValueSetter<T>(this PropertyInfo propertyInfo)
- {
- if (typeof(T) != propertyInfo.DeclaringType)
- {
- throw new ArgumentException();
- }
- var instance = Expression.Parameter(propertyInfo.DeclaringType, "i");
- var argument = Expression.Parameter(typeof(object), "a");
- var setterCall = Expression.Call(
- instance,
- propertyInfo.GetSetMethod(),
- Expression.Convert(argument, propertyInfo.PropertyType));
- return (Action<T, object>)Expression.Lambda(setterCall, instance, argument).Compile();
- }
- }
- }
|