[英]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.