测试是否Convert.ChangeType将两种类型之间的合作(Test if Convert.C

2019-07-17 12:02发布

这是一个后续行动这个问题有关与反射转换值。 转换某种类型的一个目的是另一种类型的可以这样来完成:

object convertedValue = Convert.ChangeType(value, targetType);

给定两个类型实例(说FromType和ToType),有没有办法来测试转换是否会成功吗?

例如,我可以写一个像这样的扩展方法:

public static class TypeExtensions
{
    public static bool CanChangeType(this Type fromType, Type toType)
    {
        // what to put here?
    }
}

编辑:这是我现在所拥有的。 丑陋,但我没有看到另一种方式尚未...

bool CanChangeType(Type sourceType, Type targetType)
{
  try
  {
    var instanceOfSourceType = Activator.CreateInstance(sourceType);
    Convert.ChangeType(instanceOfSourceType, targetType);
    return true; // OK, it can be converted
  }
  catch (Exception ex)
  {
    return false;
  }

Answer 1:

我只是遇到同样的问题,我用反射来看看源一changeType。 一changeType投3例异常:

  1. conversionType为null
  2. 值为null
  3. 价值没有实现IConvertible

后3那些检查,保证它可以被转换。 所以,你可以节省大量的性能和简单的检查自己的3件事移除try {} / catch语句{}块:

public static bool CanChangeType(object value, Type conversionType)
{
    if (conversionType == null)
    {
        return false;
    }

    if (value == null)
    {              
        return false;
    }

    IConvertible convertible = value as IConvertible;

    if (convertible == null)
    {
        return false;
    }

    return true;
}


Answer 2:

检查反射,我发现这个在静态构造函数的方法Convert.ChangeType:

ConvertTypes = new Type[] { 
        typeof(Empty), typeof(object), typeof(DBNull), typeof(bool), typeof(char), typeof(sbyte), typeof(byte), typeof(short), typeof(ushort), typeof(int), typeof(uint), typeof(long), typeof(ulong), typeof(float), typeof(double), typeof(decimal), 
        typeof(DateTime), typeof(object), typeof(string)
     };

最后,这种方法只是检查或者如果源是实现IConvertible或者如果目标是上面的ConvertTypes之一。 所以,你的方法应该是这个样子(非常粗略的):

return (ConvertTypes.Contains(toType) || typeof(IConvertible).IsAssignableFrom(fromType));


Answer 3:

我已经写了一个小框架,包括一个转换类,它可以做的比System.Convert类多。 如果您有兴趣使用它,你可以从这里下载Github上 。 它没有确定,如果你能值之间转换的能力,但是,似乎是一个很好的功能补充。

它包括基于将数值转换的能力:

  • IConvertible
  • 类型转换器
  • ToXxx方法
  • 解析静态方法
  • 参数的构造函数
  • 和其他一些次要的

数据类型转换



Answer 4:

基于什么已经回答了我想出了这个两个问题,(需要C#7)

public static object ChangeType(object value, Type conversion)
    {
        var type = conversion;

        if (type.IsGenericType && type.GetGenericTypeDefinition().Equals(typeof(Nullable<>)))
        {
            if (value == null)
            {
                return null;
            }

            type = Nullable.GetUnderlyingType(type);
        }

        return Convert.ChangeType(value, type);
    }

public static (bool IsSuccess, object Value) TryChangeType(object value, Type conversionType)
    {
        (bool IsSuccess, object Value) response = (false, null);
        var isNotConvertible = 
            conversionType == null 
                || value == null 
                || !(value is IConvertible)
            || !(value.GetType() == conversionType);
        if (isNotConvertible)
        {
            return response;
        }
        try
        {
            response = (true, ChangeType(value, conversionType));
        }
        catch (Exception)
        {
            response.Value = null;
        }

        return response;
    }
}

生产的代码示例:

public Item()
    {
        foreach (var pinfo in GetType().GetProperties())
        {
            object value = 0;
            var response = ReflectionHelpers.TryChangeType(value, pinfo.PropertyType);
            if(response.IsSuccess)
            {
                pinfo.SetValue(this, response.Value);
            }
        }
    }

这将启动可能与0的所有属性。



文章来源: Test if Convert.ChangeType will work between two types
标签: c# reflection