【问题标题】:What are the best practices for safely parsing a string?安全解析字符串的最佳实践是什么?
【发布时间】:2010-08-11 09:11:41
【问题描述】:

在 C# 中类型转换的最佳实践是什么?

   int temp=System.ConvertToInt32(Request.QueryString["Id"]);
    if (temp!=null)
      { // logic goes here }

如果 Id 以某种方式被证明是 'abc',这将失败

请建议使用三元运算符和除 if else 语句之外的其他单行语句(例​​如使用单行三元运算符)。另外,你们更喜欢 TryParse 而不是 Convert 以及为什么会这样?有你的家伙说。

【问题讨论】:

  • Temp 永远不会在上面为空

标签: c# .net coding-style


【解决方案1】:

TryParse 有一个明显的优势,在失败的情况下它会返回 false 而不是抛出异常。

标准模式是这样的:

int value;
if (int.TryParse(Request.QueryString["Id"], out value))
{
    // Use value
}
else
{
    // Do whatever you want on failure
}

现在,还值得牢记的是,您可以给 int.TryParse 一个 IFormatProvider 和一个 NumberStyles - 例如,您可能希望将 CultureInfo.InvariantCulture 指定为 IFormatProvider,如果这是真的成为自动生成的 ID(而不是用户输入的 ID)。

如果你想有效地拥有“默认值”,你可以编写一个这样的辅助方法:

public static int? NullableTryParseInt32(string text)
{
    int value;
    return int.TryParse(text, out value) ? value : (int?) null;
}

然后你可以像这样使用它:

int value = NullableTryParseInt32(text) ?? 10;

当然,您也可以编写一个采用默认值的方法 :)

【讨论】:

  • 您好乔恩,感谢您的回复。您将如何使用三元运算符执行该语句?每次我评估、匹配或不匹配时,不是都初始化了“out”吗?我们不应该仅仅因为这个而避免 tryParse 吗?
  • @Popo: 是的,out 参数以任何一种方式初始化,但你为什么要避免TryParse 呢?在默认值有意义的情况下,我添加了另外几个选项来简化这一点 - 但通常第一种形式确实是要使用的形式。
  • 谢谢 Jon,TryParse 是否只返回 true/false ?我可以像 Sunrisas 在使用 Convert 时那样检查 TryParse 中的异常吗?
【解决方案2】:

当涉及到解决具有多个类似解决方案的任何问题时,我也会尝试找到一个能够向代码读者表达我正在尝试完成 cleæret 的问题。在我看来,这意味着在这种特殊情况下使用 .TryParse。

使用 TryParse 告诉读者你不能保证输入是有效的(如果你是我会使用 parse 代替) 而且由于您实际上是在尝试将输入解析为 int,因此您不妨让代码读取 Line your intent

【讨论】:

    【解决方案3】:

    你有两种方法可以做到这一点

    int i;
    if (Int32.TryParse(Request.QueryString["Id"], out i))
    {
    }
    

    或者你可以这样做:

    try
    {
         Convert.ToInt32(Request.QueryString["Id"]);
    }
    catch (FormatException ex)
    {
       // The field Id it's not convertible
    }
    catch (Exception ex)
    {
       // It could throw also ArgumentException or OverflowException
    }
    

    【讨论】:

    • 您好 sinrisas,如何在 tryParse 中捕获异常?
    • 嗯,你可以把它放到一个try catch语句中。据我所知,TryParse 可以抛出的唯一异常是 ArgumentException,但在这种情况下,我想你总是会向它传递一个字符串,所以你永远不会得到这样的异常。 TryParse 背后的想法是不使用 try catch 语句,因为它根据转换的成功返回 true 或 false
    【解决方案4】:

    【讨论】:

      【解决方案5】:

      使用 TryParse 将是最佳选择。从 convert 方法捕获异常是昂贵的操作。当然 TryParse 只接受字符串,而 Convert.ToInt32 将接受对象,并且除了解析之外还可以执行转换(拆箱、从 long/double 向下转换)。

      【讨论】:

        【解决方案6】:

        涵盖此问题的三元运算符方面:

        我对使用三元运算符的建议是,如果您对所讨论的代码还不是很熟悉以至于它对您来说很自然,就不要使用它们。简洁让熟悉的更熟悉,让陌生的陌生。

        当您已经深入了解了关于 TryParse 的讨论,以至于您甚至不需要再有意识地思考它时,从 if-else 到 ?: 的转换将不仅是微不足道的,而且是自动的。在那之前,您只会增加自己的困惑。

        当我对某些东西不熟悉时,我会先下拉到“baby-speak”代码,学习新事物,然后将其融入我正常的更简洁的风格中。

        【讨论】:

          【解决方案7】:

          使用 int 类的 TryParse 方法。

          int temp;
          if (int.TryParse(Request.QueryString["Id"], out temp)
            { // logic goes here }
          

          如果 id 不包含数字 TryParse 将返回 false。

          更新:更改为显示 int.TryParse

          【讨论】:

          • string 似乎没有适合我的 tryparse 方法...您确定您不是要输入 int.TryParse?
          • 这里不是担心的温度吗?
          • 我认为你的意思是使用 int.TryParse 没有 string.TryParse,毕竟你为什么要将字符串解析成字符串 ;-)
          猜你喜欢
          • 2010-11-10
          • 2011-03-17
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-09-29
          • 2012-07-28
          相关资源
          最近更新 更多