我正在开发一个工具,我需要将字符串值转换为正确的对象类型。例如,将字符串转换"2008-11-20T16:33:21Z"
为DateTime
值。"42"
像和这样的数值"42.42"
必须分别转换为一个Int32
值和一个Double
值。
检测字符串是整数还是数字的最佳和最有效的方法是什么?是Int32.TryParse
或Double.TryParse
要走的路吗?
我正在开发一个工具,我需要将字符串值转换为正确的对象类型。例如,将字符串转换"2008-11-20T16:33:21Z"
为DateTime
值。"42"
像和这样的数值"42.42"
必须分别转换为一个Int32
值和一个Double
值。
检测字符串是整数还是数字的最佳和最有效的方法是什么?是Int32.TryParse
或Double.TryParse
要走的路吗?
Int.TryParse
并Double.TryParse
有实际返回号码的好处。
类似的东西Regex.IsMatch("^\d+$")
的缺点是您仍然必须再次解析字符串才能获取值。
就效率而言,是的,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);
我会亲自推荐 .TryParse() 。反正我就是这么用的。那就是如果您的数据不时出现错误。如果您确定传入的字符串能够毫无障碍地转换为整数或双精度数,那么 .Parse() 会更快。
这是一个有趣的链接来支持这一点。
保持转换器跳过开关块的想法,您可以使用 Duck Typing 的概念。基本上,您想将字符串转换为 X,因此您创建了一个方法,如果 X 上有 TryParse,则该方法将调用 X.TryParse(string, out 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>();
我讨厌堵住自己,但我在这里充分解释了这一点: