, , Func<object, object> . GetProperty/GetField GetValue.
- - System.Linq.Expressions.Expression:
public static class SelectorFactory
{
public static Func<object, object> GetSelector(Type type, string memberPath)
{
return CreateSelector(type, memberPath);
}
static Func<object, object> CreateSelector(Type type, string memberPath)
{
var parameter = Expression.Parameter(typeof(object), "source");
var source = Expression.Convert(parameter, type);
var value = memberPath.Split('.').Aggregate(
(Expression)source, Expression.PropertyOrField);
if (value.Type.IsValueType)
value = Expression.Convert(value, typeof(object));
var selector = Expression.Lambda<Func<object, object>>(value, parameter);
return selector.Compile();
}
}
:
var selector = SelectorFactory.GetSelector(typeof(FirstObject), "sO.tO.fO.neededValue");
var item = new FirstObject { sO = new SecondObject { tO = new ThirdObject { fO = new FourthObject { neededValue = "Ivan" } } } };
var value = selector(item);
P.S. , ( ), , - , , :
static readonly Dictionary<Tuple<Type, string>, Func<object, object>> selectorCache = new Dictionary<Tuple<Type, string>, Func<object, object>>();
public static Func<object, object> GetSelector(Type type, string memberPath)
{
var key = Tuple.Create(type, memberPath);
Func<object, object> value;
lock (selectorCache)
{
if (!selectorCache.TryGetValue(key, out value))
selectorCache.Add(key, value = CreateSelector(type, memberPath));
}
return value;
}