Created
October 5, 2018 20:50
-
-
Save brandonmartinez/da5c7493167b1dcb5f7574b406111dc5 to your computer and use it in GitHub Desktop.
Wrote some code for a project, but ended up scrapping it since we refactored and simplified the calling code. Just wanted to keep the code in case I need to mess with expressions for property getters and setters again.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Linq.Expressions; | |
using System.Reflection; | |
namespace MyProject.Services.SystemExtensions | |
{ | |
public static class ExpressionExtensions | |
{ | |
/// <summary> | |
/// Compiles a getter Func from an expression to access a property | |
/// </summary> | |
/// <typeparam name="TModel"></typeparam> | |
/// <typeparam name="TProperty"></typeparam> | |
/// <param name="propertyExpression"></param> | |
/// <returns></returns> | |
public static Func<TModel, TProperty> CompilePropertyExpressionsGetter<TModel, TProperty>(this Expression<Func<TModel, TProperty>> propertyExpression) | |
{ | |
var compiledGetter = propertyExpression.Compile(); | |
return compiledGetter; | |
} | |
/// <summary> | |
/// Generates a setter action that can be used with a property expression | |
/// </summary> | |
/// <typeparam name="TModel"></typeparam> | |
/// <typeparam name="TProperty"></typeparam> | |
/// <param name="propertyExpression"></param> | |
/// <returns></returns> | |
public static Action<TModel, TProperty> CompilePropertyExpressionsSetter<TModel, TProperty>(this Expression<Func<TModel, TProperty>> propertyExpression) | |
{ | |
if(!(propertyExpression.Body is MemberExpression member)) | |
{ | |
throw new ArgumentException($"Expression '{propertyExpression}' refers to a method, not a property."); | |
} | |
var propertyInfo = member.Member as PropertyInfo; | |
if(propertyInfo == null) | |
{ | |
throw new ArgumentException($"Expression '{propertyExpression}' refers to a field, not a property."); | |
} | |
var propertyName = propertyInfo.Name; | |
var targetExpression = Expression.Parameter(typeof(TModel), "Target"); | |
var fieldExpression = Expression.Property(targetExpression, propertyName); | |
var valueExpression = Expression.Parameter(typeof(TProperty), "value"); | |
var convertExpression = Expression.Call(typeof(Convert), "ChangeType", null, valueExpression, Expression.Constant(fieldExpression.Type)); | |
var valueCast = Expression.Convert(convertExpression, fieldExpression.Type); | |
var assignmentExpression = Expression.Assign(fieldExpression, valueCast); | |
var assignmentLambdaExpression = Expression.Lambda<Action<TModel, TProperty>>(assignmentExpression, targetExpression, valueExpression); | |
var compiledAssignment = assignmentLambdaExpression.Compile(); | |
return compiledAssignment; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment