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

Mig*_*ura 8 c#

我试图从String aa泛型转换.泛型类型将是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;

  }

}
Run Code Online (Sandbox Code Playgroud)

第二个更通用,因为它接受一个Object.

我也在考虑在TryChangeType中传递一个IFormatProvider,它将在Convert.ChangeType中用于解决文化问题,等等.

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

我可以用任何方式改进我的代码吗?

pij*_*olu 9

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

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

在第二个例子中,为什么不让它更通用并传入一个泛型类型呢?

Convert 仅当类型实现 IConvertible 接口时才有效,因此您可以检查它,另一方面,它仍然不能确保转换是可能的。

        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;
    }
Run Code Online (Sandbox Code Playgroud)

最好只捕获您知道的异常:

            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
        }
Run Code Online (Sandbox Code Playgroud)

这可能不能完全回答这个问题,但你要求可能的改进,所以我想为什么不。