11

我正在开发一个工具,我需要将字符串值转换为正确的对象类型。例如,将字符串转换"2008-11-20T16:33:21Z"DateTime值。"42"像和这样的数值"42.42"必须分别转换为一个Int32值和一个Double值。

检测字符串是整数还是数字的最佳和最有效的方法是什么?是Int32.TryParseDouble.TryParse要走的路吗?

4

4 回答 4

20

Int.TryParseDouble.TryParse有实际返回号码的好处。

类似的东西Regex.IsMatch("^\d+$")的缺点是您仍然必须再次解析字符串才能获取值。

于 2008-11-20T15:41:50.153 回答
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);
于 2008-11-20T15:40:52.400 回答
2

我会亲自推荐 .TryParse() 。反正我就是这么用的。那就是如果您的数据不时出现错误。如果您确定传入的字符串能够毫无障碍地转换为整数或双精度数,那么 .Parse() 会更快。

这是一个有趣的链接来支持这一点。

于 2008-11-20T15:46:23.793 回答
0

保持转换器跳过开关块的想法,您可以使用 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>();

我讨厌堵住自己,但我在这里充分解释了这一点:

获取正确方法信息

其余的

于 2008-11-20T16:08:54.577 回答