/// <summary> /// Takes an expression which is expected to be a member access expression (e.g. x.Prop1.Field2.Prop3), and returns a setter for setting that member on that target. /// </summary> /// <typeparam name="T"></typeparam> /// <param name="memberAccess"></param> /// <returns></returns> public static Action <T> CreateSetter <T>(Expression <Func <T> > memberAccess) { if (!(memberAccess.Body is MemberExpression)) { throw IEDebug.Exception(null, "The topmost expression must be a simple member access expression."); } return(v => CreateSetter((MemberExpression)memberAccess.Body)(v)); }
public static Parser <UpdateConfiguration> BuildKeyValueParser <T>( string keyName, Parser <T> valueParser, Expression <Func <ConnectionConfiguration, T> > getter) { return (from key in Parse.CaseInsensitiveString(keyName).Token() from separator in Parse.Char('=') from value in valueParser select(Func <ConnectionConfiguration, ConnectionConfiguration>)(c => { CreateSetter(getter)(c, value); return c; })); }
private static UpdateConfiguration BuildKeyValueParser <T>( string keyName, Func <string, T> valueParser, Expression <Func <ConnectionConfiguration, T> > getter ) { return((configuration, keyValues) => { if (keyValues != null && keyValues.TryGetValue(keyName, out var keyValue)) { var parsedValue = valueParser(keyValue); CreateSetter(getter)(configuration, parsedValue); } return configuration; }); }
private T CloneWithMembers <T>(T source, IReadOnlyCollection <Tuple <MemberInfo, MemberTypes, CloningMode> > members) { var copy = CreateInstance(source); _cloned.Add(source, copy); foreach (var member in members) { if (member.Item3 == CloningMode.Ignore) { continue; } Func <object> valueGetter; Action <object, object> valueSetter; Func <object> structValueGetter; Action <object, object> structValueSetter; switch (member.Item2) { case MemberTypes.Property: var property = member.Item1 as PropertyInfo; valueGetter = () => CreatePropGetter <T, object>(property)(source); valueSetter = (target, value) => CreatePropSetter <T, object>(property)((T)target, value); structValueGetter = () => property.GetValue(source); structValueSetter = (target, value) => property.SetValue(target, value); break; case MemberTypes.Field: var field = member.Item1 as FieldInfo; valueGetter = () => CreateGetter <T, object>(field)(source); valueSetter = (target, value) => CreateSetter <T, object>(field)((T)target, value); structValueGetter = () => field.GetValue(source); structValueSetter = (target, value) => field.SetValue(target, value); break; default: throw new ArgumentException("Only filed and property cloning supported."); } object sourceValue = null; if (_type.IsValueType) { sourceValue = structValueGetter(); } else { sourceValue = valueGetter(); } if (sourceValue == null) { continue; } var clone = CloneMakerFactory.GetCloneMaker(sourceValue, member.Item3, _typeMembers, _cloned).Clone(sourceValue, member.Item3); if (_type.IsValueType) { object boxed = copy; structValueSetter(boxed, clone); copy = (T)boxed; _cloned[source] = copy; } else { valueSetter(copy, clone); } } return(copy); }