private InitExpressionResult <Func <T, T, T> > CreateCoalesceWith( ConstructorInfo constructor) { var readableProperties = new List <PropertyInfo>( from p in typeof(T).GetRuntimeProperties() where p.CanRead select p); var readonlyProperties = new HashSet <PropertyInfo>( from p in readableProperties where false == p.CanWrite select p); var settableProperties = new HashSet <PropertyInfo>( from p in readableProperties where p.CanWrite select p); ParameterExpression left = Parameter(typeof(T), nameof(left)); ParameterExpression right = Parameter(typeof(T), nameof(right)); var arguments = new List <Expression>(); foreach (ParameterInfo parameter in constructor.GetParameters()) { PropertyInfo property = PickParameterMatch(readonlyProperties, parameter) ?? PickParameterMatch(settableProperties, parameter); if (property == null) { InitExpressionError error = GetNoPropertyMatchesParameterError( constructor, parameter); return(InitExpressionResult <Func <T, T, T> > .WithError(error)); } arguments.Add(CoalesceOrMemberAccess(property, left, right)); } if (readonlyProperties.Any()) { InitExpressionError error = GetPropertyCannotBeSetError( constructor, readonlyProperties); return(InitExpressionResult <Func <T, T, T> > .WithError(error)); } MemberInitExpression memberInitExpression = MemberInit( New(constructor, arguments), from property in settableProperties select Bind( property, CoalesceOrMemberAccess(property, left, right))); Expression <Func <T, T, T> > lambdaExpression = Lambda <Func <T, T, T> >(memberInitExpression, left, right); return(new InitExpressionResult <Func <T, T, T> >(lambdaExpression)); }
public static InitExpressionResult <TDelegate> WithError( InitExpressionError error) { if (error == null) { throw new ArgumentNullException(nameof(error)); } return(new InitExpressionResult <TDelegate>(new[] { error })); }