internal static Expression ImplicitConvert(Expression expression, Type expectedType)
{
if (expectedType == null)
{
return expression;
}
if (expectedType.IsGenericParameter)
{
if (!expectedType.IsAppropriate(expression.Type))
{
return null;
}
}
else
{
if ((expectedType.IsAppropriate(expression.Type) && expression.Type.IsValueType && !expectedType.IsValueType)
|| expectedType.GetMethod("op_Implicit", BindingFlags.Public | BindingFlags.Static, null, new [] { expression.Type, }, null) != null
)
{
return Convert(expression, expectedType);
}
if (!expectedType.IsAppropriate(expression.Type))
{
if (Nullable.GetUnderlyingType(expectedType).Let(t => t != null && t == expression.Type))
{
return Convert(expression, typeof(Nullable<>).MakeGenericType(expression.Type));
}
else if (Nullable.GetUnderlyingType(expression.Type).Let(t => t != null && t == expectedType))
{
return Convert(expression, Nullable.GetUnderlyingType(expression.Type));
}
return ConvertNumericType(expression.Type, expectedType)
.Null(t => Convert(expression, t));
}
}
return expression;
}