LINQ查询中的Decimal.TryParse-如何使用out参数并避免第二次转换

时间:2019-02-21 20:48:20

标签: c# linq-to-xml tryparse

我正在使用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);

我的问题是我是否可以利用out的{​​{1}}参数而不是第二次执行十进制转换?

3 个答案:

答案 0 :(得分:3)

只需按照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);

答案 1 :(得分:1)

是的,您可以这样做:

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);

您可以使用&&将AND内的多个断言链接在一起。

答案 2 :(得分:1)

尝试编写将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);