繁体   English   中英

通用类型转换器-TypeConverter或Convert.ChangeType

[英]Generic Type Converter - TypeConverter or Convert.ChangeType

我正在尝试从String转换成通用类型。 通用类型将是Int32,Int64,Boolean,Double等。我尝试了两种方法:

public static Boolean TryParse<T>(String source, out T value) {

  TypeConverter converter = TypeDescriptor.GetConverter(typeof(T));

  try {

    value = (T)converter.ConvertFromString(source);
    return true;

  } catch {

    value = default(T);
    return false;

  }

}

public static Boolean TryChangeType<T>(Object source, out T value) {

  try {

    Type type = Nullable.GetUnderlyingType(typeof(T)) ?? typeof(T);

    value = (T)Convert.ChangeType(source, type);
    return true;

  } catch {

    value = default(T);
    return false;

  }

}

第二个更通用,因为它接受一个对象。

我还考虑在TryChangeType中传递IFormatProvider,该IFormatProvider将在Convert.ChangeType中用于解决区域性问题,等等。

您认为第二种方法更好吗?

有什么办法可以改善我的代码吗?

在您的第一个示例中,您可以通过预先调用CanConvertTo()CanConvertFrom()摆脱try catch块。

public static bool TryParse<T>(string source, out T value)
{
    TypeConverter converter = TypeDescriptor.GetConverter(typeof (T));
    if (converter.CanConvertTo(typeof (T)) && converter.CanConvertFrom(typeof (string)))
    {
        value = (T)converter.ConvertFromString(source);
        return true;
    }
    else
    {
        value = default (T);
        return false;
    }
}

在第二个示例中,为什么不使其更通用并传递通用类型呢?

仅当类型实现接口IConvertible时, Convert才起作用,因此您可以进行检查,另一方面,stil不能确保可以进行转换。

        public static bool TryChangeType<T, TR>(T input, out TR output) where T : IConvertible
    {
        bool result = false;
        try
        {
            Type type = Nullable.GetUnderlyingType(typeof(TR));
            output = (TR)Convert.ChangeType(input, type);
            result = true;
        }
        catch(Exception)
        {
            output = default(TR);
        }
        return result;
    }

仅捕获您所知道的异常将是很好的:

            catch(InvalidCastException)
        {
            output = default(TR);
            //Conversion is not unsupported
        }
            catch(FormatException)
        {
            output = default(TR);
            //string input value was in incorrect format
        }
            catch(InvalidCastException)
        {
            output = default(TR);
            //Conversion is not unsupported
        }
            catch(OverflowException)
        {
            output = default(TR);
            //narrowing conversion between two numeric types results in loss of data
        }

这可能无法完全回答问题,但是您正在寻求可能的改进,所以我想为什么不这样做。

第二个仅适用于IConvertible类型。 如果这是您想要的,那么您可能也想应用一个约束(无论如何, ChangeType都会为不可转换类型抛出异常):

public static Boolean TryChangeType<T>(Object source, out T value)
    where T : IConvertible
{
    // ...
}

第一个比较笼统,当应使用.NET组件模型时,将使用TypeConverter 例如,在设计人员中,类型转换器用于从属性网格中的字符串转换值。 但是您也应该在此处添加一个小的附加检查:

if (!converter.CanConvertFrom(typeof(string)))
    return false;

另外,我要提到的是,如果您不希望对其他区域设置感到麻烦(例如,在浮点值的情况下),则应使用ConvertFromInvariantString方法...

在第一个示例中, TypeDescriptor.GetConverter(Type)可以引发异常,因此将其移入try块。 如果没有亲自尝试,则从您的两种方法中我都喜欢第二种。

这篇文章展示了一个没有可尝试性/可移植性的可转换性测试示例,并声称具有性能优势。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM