private static void ValidateAsyncLambdaArgs(Type delegateType, ref Expression body, ReadOnlyCollection <ParameterExpression> parameters) { //ContractUtils.RequiresNotNull(delegateType, nameof(delegateType)); //TODO: Verify //RequiresCanRead(body, nameof(body)); if (!typeof(MulticastDelegate).IsAssignableFrom(delegateType) || delegateType == typeof(MulticastDelegate)) { throw LinqError.LambdaTypeMustBeDerivedFromSystemDelegate(); } var count = parameters.Count; var method = delegateType.GetMethod("Invoke"); // TODO: use cache from LINQ var parametersCached = method.GetParametersCached(); if (parametersCached.Length != 0) { if (parametersCached.Length != count) { throw LinqError.IncorrectNumberOfLambdaDeclarationParameters(); } var set = new Set <ParameterExpression>(count); for (var i = 0; i < count; i++) { var parameter = parameters[i]; ValidateAsyncParameter(parameter); var parameterType = parametersCached[i].ParameterType; if (!TypeUtils1.AreReferenceAssignable(parameter.Type, parameterType)) { throw LinqError.ParameterExpressionNotValidAsDelegate(parameter.Type, parameterType); } if (set.Contains(parameter)) { throw LinqError.DuplicateVariable(parameter); } set.Add(parameter); } } else if (count > 0) { throw LinqError.IncorrectNumberOfLambdaDeclarationParameters(); } var returnType = method.ReturnType; if (returnType.IsGenericType && returnType.GetGenericTypeDefinition() == typeof(Task <>)) { var resultType = returnType.GetGenericArguments()[0]; if (!TypeUtils1.AreReferenceAssignable(resultType, body.Type) && !TryQuote(resultType, ref body)) { throw LinqError.ExpressionTypeDoesNotMatchReturn(body.Type, method.ReturnType); } } else if (returnType != typeof(void) && returnType != typeof(Task)) { throw Error.AsyncLambdaInvalidReturnType(returnType); } }