Skip to content

Instantly share code, notes, and snippets.

@deepumi
Created June 18, 2019 14:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save deepumi/b9af481f628c58928d35bcff7052f19f to your computer and use it in GitHub Desktop.
Save deepumi/b9af481f628c58928d35bcff7052f19f to your computer and use it in GitHub Desktop.
Poco property setter using Expressions tress.
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Reflection;
internal sealed class PropertySetter<T>
{
private const BindingFlags Flags = BindingFlags.Public | BindingFlags.Instance | BindingFlags.IgnoreCase;
private readonly Type _type = typeof(T);
private readonly Dictionary<string, Action<T, object>> _setterDictionary;
public PropertySetter(int fieldCount)
{
_setterDictionary = new Dictionary<string, Action<T, object>>(fieldCount, StringComparer.OrdinalIgnoreCase);
}
internal bool Set(T instance, object value, string propertyName)
{
if (_setterDictionary.ContainsKey(propertyName))
{
_setterDictionary[propertyName](instance, value);
return true;
}
var p = _type.GetProperty(propertyName, Flags);
if (p == null) return false;
var typeParameter = Expression.Parameter(typeof(T));
var valueParameter = Expression.Parameter(typeof(object));
var setter = Expression.Lambda<Action<T, object>>(
Expression.Assign(
Expression.Property(
Expression.Convert(typeParameter, _type), p),
Expression.Convert(valueParameter, p.PropertyType)),
typeParameter, valueParameter);
_setterDictionary.Add(propertyName, setter.Compile());
_setterDictionary[propertyName](instance, value);
return true;
}
internal void Clear() => _setterDictionary.Clear();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment