如何在C#中判断一个字符串是否为数字

11

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

检测一个字符串是整数还是数字的最佳和最有效的方法是什么?Int32.TryParseDouble.TryParse是否是正确选择?

4个回答

20

Int.TryParseDouble.TryParse 具有实际返回数字的好处。

Regex.IsMatch("^\d+$") 这样的内容有一个缺点,你仍然需要再次解析字符串才能获取值。


另一个附加的好处是TryParse方法返回一个布尔变量,因此在解析数字时轻松编写成功和失败场景的代码。 - Dillie-O
但如果你只关心它是否为整数,TryParse有一个优点,就是需要你声明一个用于输出参数的变量。 - Louis Rhys

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
我个人建议使用 .TryParse()。无论如何,这就是我使用的方法。如果您确定传入的字符串可以毫无问题地转换为整数或双精度浮点数,则 .Parse() 更快。

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


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

虽然我不太喜欢自吹自擂,但是我已经在这里详细解释了:

GetCorrectMethodInfo

其余部分


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接