【问题标题】:Combined null and value check结合空值和值检查
【发布时间】:2015-11-10 11:32:14
【问题描述】:

这段代码运行良好:

policy.ProviderID > 0 ? RefDataSources.LegalBodies.GetDisplayName(policy.ProviderID.Value) : null

但 Resharper 抱怨 policy.ProviderID.Value 需要检查 null(以防止出现 InvalidOperationException)。

据我所知,该条件只会对大于0 的非空值评估为真,因此不需要进一步检查。

我应该将此记录为 JetBrains 的错误吗? 还是我误解了什么。

【问题讨论】:

  • policy.ProviderID的类型是什么?
  • @Matt 显然是int?
  • @IvanStoev,你是怎么得出这个结论的?我看不到任何可以确认它是那种类型的东西。
  • @AshBurlaczenko:看起来它是某种数字类型的可为空值类型,以便与 0 进行比较。我同意肯定会知道,但我认为它是目前是一个合理的猜测。
  • @JonSkeet,我在玩魔鬼倡导者:) 我同意 int?很可能是这种类型,我只是指出还有其他可能性。

标签: c# null resharper evaluation


【解决方案1】:

我怀疑 R# 是在抱怨,因为它不知道 policy.ProviderID 会在两次评估中返回相同的值。考虑:

private readonly int? providerId;

public int? EvilProviderId => DateTime.UtcNow.Second == 0 ? null : providerId;

现在考虑您的代码 - 条件 可能为真,因为第一次调用是在 59 秒执行的...但是时钟在第二次调用之前滴答作响,然后返回 null,导致NullReferenceException.

如果这 R# 抱怨的原因,只需提取一个局部变量:

int? providerId = policy.ProviderId;
// Use providerId in both cases in your expression

【讨论】:

  • 我在本地得到相同的行为。但是,将其更改为 var t = p.ProviderID.HasValue ? (int?)p.ProviderID.Value : null; 会删除警告,但仍然容易受到您概述的情况的影响。这可能是由于 R# 没有将 int? 与任何其他 Nullable<T> 区分开来,其中 T 可能有运算符重载。不过很有趣
  • 此外,您对提取局部变量的修复实际上也消除了警告。
  • 我模糊地想到了这一点,但如果 "> 0" 检查被替换(或补充)为“!= null”,那么 Resharper 会删除警告,所以我认为它一定是别的东西。跨度>
  • @SimonHewitt:我怀疑启发式方法非常复杂......我建议无论如何都使用“提取局部变量”版本。
  • 这次我一定是在 Resharper 网站上使用了更好的关键字,因为我发现这个问题已经在 link 报告了。我刚刚安装的 v10 中仍然存在问题,所以给了它一个问题。
【解决方案2】:

改用这个:

(policy != null && policy.ProviderID.HasValue &&  policy.ProviderID. Value > 0) ? RefDataSources.LegalBodies.GetDisplayName(policy.ProviderID.Value) : null

【讨论】:

  • 哇,所有这些只是为了让 ReSharper 开心?如果属性在调用之间没有发生变化,则 OP 代码是完全正确的,但如果发生了变化,您的代码 sn-p 也将不起作用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-04-08
  • 2019-06-18
  • 1970-01-01
  • 1970-01-01
  • 2010-11-13
  • 1970-01-01
  • 2013-05-16
相关资源
最近更新 更多