public static int CanBeConverted(this Type sourceType, Type targetType) { if (sourceType == targetType) { return(0); } try { var e = Expression.Convert(Expression.Parameter(sourceType), targetType); return(1); } catch (Exception) { var method = ConverterHelper.GetConvertMethod(sourceType, targetType); if (method != null) { return(2); } } return(-1); }
/// <summary> /// return an expression of convertion if targetype are differents /// </summary> /// <param name="self"></param> /// <param name="targetType"></param> /// <returns></returns> public static Expression ConvertIfDifferent(this Expression self, Type targetType) { Expression result = null; Type sourceType = self.ResolveType(); if (sourceType != targetType) { //if (self is ConstantExpression c) //{ // result = c.Value.AsConstant(targetType); // if (result.Type != targetType) // result = Expression.Convert(result, targetType); //} //else //{ try { result = Expression.Convert(self, targetType); } catch (Exception) // not managed { var method = ConverterHelper.GetConvertMethod(sourceType, targetType); if (method != null) { var parameters = method.GetParameters(); Expression[] arguments = new Expression[parameters.Length]; if (parameters[0].ParameterType == sourceType) { arguments[0] = self; } else if (typeof(IFormatProvider).IsAssignableFrom(parameters[0].ParameterType)) { arguments[0] = Expression.Constant(CultureInfo.CurrentCulture); } else if (parameters[0].ParameterType.IsAssignableFrom(sourceType)) { arguments[0] = ConvertIfDifferent(self, parameters[0].ParameterType); } else if (parameters[0].ParameterType == typeof(Type)) { arguments[0] = Expression.Constant(targetType); } else { } if (parameters[1].ParameterType == sourceType) { arguments[1] = self; } else if (typeof(IFormatProvider).IsAssignableFrom(parameters[1].ParameterType)) { arguments[1] = Expression.Constant(CultureInfo.CurrentCulture); } else if (parameters[1].ParameterType.IsAssignableFrom(sourceType)) { arguments[1] = ConvertIfDifferent(self, parameters[0].ParameterType); } else if (parameters[1].ParameterType == typeof(Type)) { arguments[1] = Expression.Constant(targetType); } else { } if (method is MethodInfo m) { if (m.IsStatic) { result = Expression.Call(null, m, arguments); } else { result = Expression.Call(self, m, arguments); } } else if (method is ConstructorInfo ctor) { result = Expression.New(ctor, arguments); } } if (result == null) { if (targetType != typeof(object)) { result = self.ConvertIfDifferent(typeof(object)); result = result.ConvertIfDifferent(targetType); } else { throw; } } } //} } else { result = self; } return(result); }