在可为空的十进制属性上使用 Math.Abs

Posted

技术标签:

【中文标题】在可为空的十进制属性上使用 Math.Abs【英文标题】:Using Math.Abs on nullable decimal property 【发布时间】:2022-01-17 18:27:28 【问题描述】:

我有一个类型的对象。

class A

    public int Idget;set;
    public decimal? Num get;set;

然后我从 db 填充了 List<A> objList 数据。 我需要将 Num 设为正数,所以 我尝试执行以下操作。

objList = objList.ForEach(x=>x.Num = Math.Abs(x.Num));

由于 Num 是可以为空的 decimal ,我无法在 Linq 中使用它。如何使用它,以便我可以跳过空值并使用 Math.abs 将 -ve 值转换为 +ve 1?

【问题讨论】:

如何使用它以便我可以跳过空值 - 这不是很清楚,但如果你想删除 Num 为空的值,你可以这样做 - objList = objList.Where(o => o.Num.HasValue).Select(o => new A Id = o.Id, Num = Math.Abs(o.Num.Value) ).ToList(); @stuartd 我很确定“跳过”意味着忽略而不是从列表中删除。 @JohnathanBarclay:是的,你是对的。跳过意味着忽略它 @JohnathanBarclay 我认为这是有道理的,但值被分配回objList 【参考方案1】:

我不会使用List<T>.ForEach() 来改变列表。相反,我会使用一个简单的foreach 循环,如下所示:

foreach (var item in objList.Where(item => item.Num != null))

    item.Num = Math.Abs(item.Num!.Value);

注意:如果使用可空检查,您必须使用! 来抑制item.Num!.Value 中的警告,因为编译器不够聪明,无法确定因为Where 它不能为空。

另请注意,这种方法避免了将 null 冗余分配给已经为空的 Num,这在其他解决方案中会发生。

(请参阅Eric Lippert's post on foreach vs ForEach,了解为什么不应该使用List<T>.ForEach() 来改变列表。)

【讨论】:

Eric Lippert 讨论了为什么没有将ForEach 添加到 LINQ。唯一提到List<T>.ForEach 是您“在迭代列表时不应该对其进行变异”,但这正是您对标准foreach 所做的事情。 @JohnathanBarclay 注意 Eric 说的部分 Doing this lets you rewrite this perfectly clear code: ... into this code:。我同意他的观点,即使用List<T>.ForEach() 的代码不是很清楚。 是我想提请注意的。【参考方案2】:

ForEach 不是 LINQ 的一部分,而是List<T> 上的method defined,它返回void(因此您不能将其结果分配给objList,即objList = objList.ForEach)。

您可以使用ternary operator 来检查x.Num 是否具有价值并将该值用于Math.Abs

objList.ForEach(x => x.Num = x.Num.HasValue ? Math.Abs(x.Num.Value) : null);

【讨论】:

【参考方案3】:

ForEach 不是 LINQ,it's an instance method on List<T> 会更新列表。

Num 不为空时,您可以使用三元表达式仅应用Math.Abs

objList.ForEach(x => x.Num = x.Num is decimal d ? Math.Abs(d) : null);

【讨论】:

这不会更新任何东西吗?并且 x.Num 仍然是 decimal? 类型,无论您的空卡盘如何,所以我很确定您仍然需要使用 x.Num.Value

以上是关于在可为空的十进制属性上使用 Math.Abs的主要内容,如果未能解决你的问题,请参考以下文章

如何阻止 EF Core 在可为空的列上创建筛选索引

堆栈溢出错误可为空的数字类型c#

C# winforms:将可空类型绑定到其他属性(不是文本)时出错

Azure API 管理:使用可为空的属性验证内容

使用 XmlSerializer 将空 xml 属性值反序列化为可为空的 int 属性

如果它为空或为空,如何从序列化中忽略可为空的属性?