private static MethodInfo ResolveMethod <TService>(Expression operation, out Action callback, out object[] args) { if (operation == null) { throw new ArgumentNullException("operation"); } var lambda = operation as LambdaExpression; if (lambda == null) { throw new ArgumentException("LambdaExpression expected", "operation"); } if (lambda.Parameters.Count != 1 || lambda.Parameters[0].Type != typeof(TService)) { throw new ArgumentException("The lambda was expected to take a single argument of type " + typeof(TService)); } var call = lambda.Body as MethodCallExpression; if (call == null || call.Object != lambda.Parameters[0]) { throw new ArgumentNullException("Methods must invoked directly on the supplied service instance"); } args = new object[call.Arguments.Count]; object[] argsCpy = args; // used for capture ParameterInfo[] parameters = call.Method.GetParameters(); callback = null; for (int i = 0; i < args.Length; i++) { if (parameters[i].ParameterType.IsByRef) { FieldInfo field; object target; if (!TryResolveField(call.Arguments[i], out field, out target)) { throw new InvalidOperationException("Cannot guarantee ref/out behaviour due to expression complexity; consider simplifying the expression."); } args[i] = RpcUtils.IsRequestArgument(parameters[i]) ? field.GetValue(target) : null; int iCpy = i; // for capture callback += delegate { field.SetValue(target, argsCpy[iCpy]); }; } else { args[i] = Evaluate(call.Arguments[i]); } } return(call.Method); }