我正在开发一个工具,我需要将字符串值转换为正确的对象类型。例如。将"2008-11-20T16:33:21Z"
之类的字符串转换为DateTime
值。像"42"
和"42.42"
这样的数字值必须分别转换为Int32
值和Double
值。
检测字符串是整数还是数字的最佳和最有效的方法是什么? Int32.TryParse
还是Double.TryParse
要走的路?
答案 0 :(得分:20)
Int.TryParse
和Double.TryParse
具有实际返回数字的好处。
像Regex.IsMatch("^\d+$")
这样的东西有一个缺点,你仍然需要再次解析字符串以获取值。
答案 1 :(得分:9)
就效率而言,是的,TryParse通常是首选路线。
如果您事先知道(例如,通过反射)目标类型 - 但又不想使用大switch
块,您可能对使用TypeConverter
感兴趣 - 例如:
DateTime foo = new DateTime(2008, 11, 20);
TypeConverter converter = TypeDescriptor.GetConverter(foo);
string s = converter.ConvertToInvariantString(foo);
object val = converter.ConvertFromInvariantString(s);
答案 2 :(得分:2)
我个人会推荐.TryParse()。这就是我用的无论如何。如果您的数据一次又一次出错,那就是这样。如果你确定传入的字符串能够顺利转换为整数或双精度数,那么.Parse()会更快。
这是一个有趣的link来支持这一点。
答案 3 :(得分:0)
保持转换器跳过开关块的想法,你可以使用Duck Typing的概念。基本上,你想把一个字符串转换为X,所以如果X上有TryParse,你就创建一个调用X.TryParse(字符串,输出X x)的方法,否则你只是不打扰(或者我想你可以扔掉)一个错误)。你会怎么做?反思和泛型。
基本上你会有一个方法可以接受一个类型并使用反射来查看它是否有TryParse。如果你找到这样的方法,你就可以调用它并返回TryParse设法得到的任何东西。这适用于任何值类型,如Decimal或DateTime。
public static class ConvertFromString
{
public static T? ConvertTo<T>(this String numberToConvert) where T : struct
{
T? returnValue = null;
MethodInfo neededInfo = GetCorrectMethodInfo(typeof(T));
if (neededInfo != null && !numberToConvert.IsNullOrEmpty())
{
T output = default(T);
object[] paramsArray = new object[2] { numberToConvert, output };
returnValue = new T();
object returnedValue = neededInfo.Invoke(returnValue.Value, paramsArray);
if (returnedValue is Boolean && (Boolean)returnedValue)
{
returnValue = (T)paramsArray[1];
}
else
{
returnValue = null;
}
}
return returnValue;
}
}
GetCorrectMethodInfo看起来像这样:
private static MethodInfo GetCorrectMethodInfo(Type typeToCheck)
{
MethodInfo returnValue = someCache.Get(typeToCheck.FullName);
if(returnValue == null)
{
Type[] paramTypes = new Type[2] { typeof(string), typeToCheck.MakeByRefType() };
returnValue = typeToCheck.GetMethod("TryParse", paramTypes);
if (returnValue != null)
{
CurrentCache.Add(typeToCheck.FullName, returnValue);
}
}
return returnValue;
}
使用将是:
decimal? converted = someString.ConvertTo<decimal>();
我讨厌堵塞自己,但我在此完全解释了这一点: