private static BinaryExpression GetUserDefinedBinaryOperator(ExpressionType binaryType, string name, Expression left, Expression right, bool liftToNull)
{
// try exact match first
MethodInfo method = GetUserDefinedBinaryOperator(binaryType, left.Type, right.Type, name);
if (method != null)
{
return new MethodBinaryExpression(binaryType, left, right, method.ReturnType, method);
}
// try lifted call
if (left.Type.IsNullableType() && right.Type.IsNullableType())
{
Type nnLeftType = left.Type.GetNonNullableType();
Type nnRightType = right.Type.GetNonNullableType();
method = GetUserDefinedBinaryOperator(binaryType, nnLeftType, nnRightType, name);
if (method != null && method.ReturnType.GetTypeInfo().IsValueType && !method.ReturnType.IsNullableType())
{
if (method.ReturnType != typeof(bool) || liftToNull)
{
return new MethodBinaryExpression(binaryType, left, right, method.ReturnType.GetNullableType(), method);
}
else
{
return new MethodBinaryExpression(binaryType, left, right, typeof(bool), method);
}
}
}
return null;
}