// // Returns true if the body of lambda expression can be implicitly // converted to the delegate of type `delegate_type' // public bool ImplicitStandardConversionExists(ParseContext ec, Type delegateType) { var expressionTreeConversion = false; if (!TypeManager.IsDelegateType(delegateType)) { if (TypeManager.DropGenericTypeArguments(delegateType) != TypeManager.CoreTypes.GenericExpression) { return(false); } delegateType = delegateType.GetGenericArguments()[0]; expressionTreeConversion = true; } var invokeMethod = delegateType.GetMethod("Invoke"); // TypeManager.GetDelegateInvokeMethod(ec, null, delegateType); var returnType = invokeMethod.ReturnType; if (returnType.IsGenericParameter) { var genericArguments = delegateType.GetGenericArguments(); returnType = genericArguments[returnType.GenericParameterPosition]; } EnsureScope(ec); var delegateParameters = invokeMethod.GetParameters(); if (delegateParameters.Length != _scope.Parameters.Count) { return(false); } var lambdaParameters = ResolveParameters(ec, null, delegateType); int i = 0; var result = delegateParameters.All(delegateParameter => TypeUtils.AreAssignable(delegateParameter.ParameterType, lambdaParameters[i++].ParameterType)); if (result) { var oldScope = ec.CurrentScope; ec.CurrentScope = _scope; var resolvedBody = _body.Resolve(ec); ec.CurrentScope = oldScope; if (!TypeUtils.AreAssignable(returnType, resolvedBody.Type)) { return(false); } _body = resolvedBody; _resolvedBody = (expressionTreeConversion) ? new QuoteExpression(this) : resolvedBody; Type = _body.Type; LambdaType = delegateType; } return(result); }
/// <summary> /// Checks the two types are assignable. /// </summary> /// <param name="memberInfo">The member info.</param> /// <param name="sourceValue">The source value.</param> /// <param name="destination">The destination.</param> /// <exception cref="ReflectionHelperException">thrown when types are not assignable.</exception> internal static void CheckAreAssignable(MemberInfo memberInfo, object sourceValue, Type destination) { Type source = TypeUtils.GetType(sourceValue); if (!destination.IsValueType && sourceValue == null) { return; } if (!TypeUtils.AreAssignable(source, destination)) { throw new ReflectionHelperException(string.Format(CultureInfo.CurrentCulture, Strings.ReflectionHelper_Parameter_type_cannot_be_used_for_method, source, destination, memberInfo)); } }