Decimal.TryParse 在 LINQ 查询中 - 如何使用 out 参数并避免二次转换
Decimal.TryParse in LINQ query - How to use the out parameter and avoid second conversion
我正在使用 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
参数而不是再次执行十进制转换?
按照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);
是的,你可以这样做:
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。
尝试编写将 XElement 转换为 Decimal 的实用程序扩展方法。在这种情况下,您可以将非十进制值视为零,因为您只对正值感兴趣。如果要区分真正的0值和非十进制值,那么该方法可以return nullable decimal.
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 简单多了。这也将处理 "balance" 元素本身缺失的情况。
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);
我正在使用 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
参数而不是再次执行十进制转换?
按照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);
是的,你可以这样做:
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。
尝试编写将 XElement 转换为 Decimal 的实用程序扩展方法。在这种情况下,您可以将非十进制值视为零,因为您只对正值感兴趣。如果要区分真正的0值和非十进制值,那么该方法可以return nullable decimal.
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 简单多了。这也将处理 "balance" 元素本身缺失的情况。
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);