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);
        }