【问题标题】:Decimal.TryParse in LINQ query - How to use the out parameter and avoid second conversionLINQ 查询中的 Decimal.TryParse - 如何使用 out 参数并避免第二次转换
【发布时间】:2019-02-21 20:48:20
【问题描述】:

我正在使用 LINQ to XML 查询来遍历 XML 文件并收集余额为正的那些节点。 XML 可能有一个空的余额节点或包含无法转换为十进制的内容,因此我进行了检查以跳过这些值。其中一项检查使用decimal.TryParse()查看余额节点的内容是否可以转换为十进制。如果可以转换,我有一个后续 Where 子句来执行转换。

XML 结构:

<Invoice>
...
  <balance>Could be any string here or empty</balance>
...
</Invoice>

代码:

decimal convertedDecimalButUnused;
var resultsWithPositiveBalance = xml.Descendants("Invoice")
.Where(x => !x.Element("balance").IsEmpty);
.Where(x => Decimal.TryParse(x.Element("balance").Value, out convertedDecimalButUnused))
.Where(x => Convert.ToDecimal(x.Element("balance").Value) > 0);

我的问题是我是否可以使用decimal.TryParse()out 参数而不是第二次执行十进制转换?

【问题讨论】:

    标签: c# linq-to-xml tryparse


    【解决方案1】:

    只需按照 TryParse 进行比较即可。您可以利用 C#7 功能,允许您在行中声明值。

    例如:

    var resultsWithPositiveBalance = xml.Descendants("Invoice")
    .Where(x => !x.Element("balance").IsEmpty);
    .Where(x => Decimal.TryParse(x.Element("balance").Value, out var val) && val > 0)
    

    由于 TryParse 会为您处理元素是否已经为空,因此您也可以放弃检查。最后,你可以得到你想要的结果:

    var resultsWithPositiveBalance = xml.Descendants("Invoice")
    .Where(x => decimal.TryParse(x.Element("balance").Value, out var val) && val > 0);
    

    【讨论】:

      【解决方案2】:

      是的,您可以这样做:

      decimal convertedDecimalButUnused;
      var resultsWithPositiveBalance = xml.Descendants("Invoice")
      .Where(x => !x.Element("balance").IsEmpty);
      .Where(x => Decimal.TryParse(x.Element("balance").Value, out convertedDecimalButUnused) && convertedDecimalButUnused > 0);
      

      您可以在 Where 函数中使用等于 AND 的 &amp;&amp; 将多个断言链接在一起。

      【讨论】:

        【解决方案3】:

        尝试编写将 XElement 转换为 Decimal 的实用程序扩展方法。在这种情况下,您可以将非十进制值视为零,因为您只对正值感兴趣。如果要区分实0值和非十进制值,则该方法可以返回可为空的十进制。

        public static class UtilityExtensions {
            // return decimal? to differentiate between real zero and non-decimal values
            public static decimal ToDecimal(this XElement element){
                if(element == null || element.IsEmpty) return 0; // return null for decimal?
                decimal value;
                // if you can use C# 7, code can be more succinct with inline declaration
                return Decimal.TryParse(element.Value, out value) ? value : 0; // return null instead of 0 for decimal?
            }
        }
        

        现在您的 LINQ 更加简单。这也将处理“平衡”元素本身缺失的情况。

        var resultsWithPositiveBalance = xml.Descendants("Invoice")
                 .Where(x => !x.Element("balance").ToDecimal() > 0);
        

        如果你最终使用decimal? 版本:

        var resultsWithPositiveBalance = xml.Descendants("Invoice")
                 .Where(x => (!x.Element("balance").ToDecimal() ?? 0 ) > 0);
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2013-04-10
          • 1970-01-01
          • 1970-01-01
          • 2014-12-12
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-11-05
          相关资源
          最近更新 更多