Created
February 20, 2017 12:58
-
-
Save Zabaa/eea990c3f8f3d49dcf0433d036f77fc9 to your computer and use it in GitHub Desktop.
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
class Program | |
{ | |
static void Main(string[] args) | |
{ | |
Foo foo = new Foo(); | |
var setValue = BuildSet<Foo, string>("Bar.Name"); | |
var getValue = BuildGet<Foo, string>("Bar.Name"); | |
setValue(foo, "abc"); | |
Console.WriteLine(getValue(foo)); | |
Console.ReadLine(); | |
} | |
static Action<T, TValue> BuildSet<T, TValue>(string property) | |
{ | |
string[] props = property.Split('.'); | |
Type type = typeof(T); | |
ParameterExpression arg = Expression.Parameter(type, "x"); | |
ParameterExpression valArg = Expression.Parameter(typeof(TValue), "val"); | |
Expression expr = arg; | |
foreach (string prop in props.Take(props.Length - 1)) | |
{ | |
// use reflection (not ComponentModel) to mirror LINQ | |
PropertyInfo pi = type.GetProperty(prop); | |
expr = Expression.Property(expr, pi); | |
type = pi.PropertyType; | |
} | |
// final property set... | |
PropertyInfo finalProp = type.GetProperty(props.Last()); | |
MethodInfo setter = finalProp.GetSetMethod(); | |
expr = Expression.Call(expr, setter, valArg); | |
return Expression.Lambda<Action<T, TValue>>(expr, arg, valArg).Compile(); | |
} | |
static Func<T, TValue> BuildGet<T, TValue>(string property) | |
{ | |
string[] props = property.Split('.'); | |
Type type = typeof(T); | |
ParameterExpression arg = Expression.Parameter(type, "x"); | |
Expression expr = arg; | |
foreach (string prop in props) | |
{ | |
// use reflection (not ComponentModel) to mirror LINQ | |
PropertyInfo pi = type.GetProperty(prop); | |
expr = Expression.Property(expr, pi); | |
type = pi.PropertyType; | |
} | |
return Expression.Lambda<Func<T, TValue>>(expr, arg).Compile(); | |
} | |
} | |
class Foo | |
{ | |
public Foo() { Bar = new Bar(); } | |
public Bar Bar { get; private set; } | |
} | |
class Bar | |
{ | |
public string Name { get; set; } | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment