17 using System.Collections.Generic;
18 using System.Diagnostics;
20 using System.Linq.Expressions;
34 private readonly Func<IReadOnlyList<OptionPosition>,
OptionPosition,
bool> _predicate;
35 private readonly Expression<Func<IReadOnlyList<OptionPosition>,
OptionPosition,
bool>> _expression;
40 public bool IsIndexed => _comparison !=
null && _reference !=
null;
53 Func<IReadOnlyList<OptionPosition>,
OptionPosition,
bool> predicate,
54 Expression<Func<IReadOnlyList<OptionPosition>,
OptionPosition,
bool>> expression
57 _reference = reference;
58 _predicate = predicate;
59 _comparison = comparison;
60 _expression = expression;
71 return _predicate(legs, position);
73 catch (InvalidOperationException)
93 positions.Where(position => _predicate(legs, position))
97 var referenceValue = _reference.Resolve(legs);
98 switch (_reference.Target)
104 throw new ArgumentOutOfRangeException();
120 Expression<Func<IReadOnlyList<OptionPosition>,
OptionPosition,
bool>> expression
139 var legsParameter = expression.Parameters[0];
140 var positionParameter = expression.Parameters[1];
141 var binary = expression.OfType<BinaryExpression>().Single(e => e.NodeType.IsBinaryComparison());
143 var leftReference = CreateReferenceValue(legsParameter, positionParameter, binary.Left);
144 var rightReference = CreateReferenceValue(legsParameter, positionParameter, binary.Right);
145 if (leftReference !=
null && rightReference !=
null)
147 throw new ArgumentException($
"The provided expression is not of the required form: {expression}");
152 var reference = rightReference;
153 if (rightReference ==
null)
155 reference = leftReference;
156 comparison = comparison.FlipOperands();
174 Expression legsParameter,
175 Expression positionParameter,
176 Expression expression
182 var expressions = expression.AsEnumerable().ToList();
183 var containsLegParameter = expressions.Any(e => ReferenceEquals(e, legsParameter));
184 var containsPositionParameter = expressions.Any(e => ReferenceEquals(e, positionParameter));
185 if (containsPositionParameter)
187 if (containsLegParameter)
189 throw new NotSupportedException(
"Expressions containing references to both parameters " +
190 "(legs and positions) on the same side of an equality operator are not supported."
199 if (!containsLegParameter)
202 var value = Expression.Lambda(expression).Compile().DynamicInvoke();
205 throw new ArgumentNullException($
"Failed to evaluate expression literal: {expressions}");
208 return ConstantOptionStrategyLegReferenceValue.Create(value);
212 var methodCall = expressions.Single<MethodCallExpression>();
213 Debug.Assert(methodCall.Method.Name ==
"get_Item");
215 var arrayIndex = (int) Expression.Lambda(methodCall.Arguments[0]).Compile().DynamicInvoke();
218 var member = expressions.Single<MemberExpression>().Member;
219 var target = GetPredicateTargetValue(member.Name);
221 return new OptionStrategyLegPredicateReferenceValue(arrayIndex, target);
232 throw new NotImplementedException(
233 $
"Failed to resolve member name '{memberName}' to {nameof(PredicateTargetValue)}"
242 return _expression.ToString();