【问题标题】:How do I get rid of "Possible System.NullReferenceException" warnings when using LINQ and ReSharper?使用 LINQ 和 ReSharper 时如何摆脱“可能的 System.NullReferenceException”警告?
【发布时间】:2011-09-15 18:52:40
【问题描述】:

假设我有以下代码:

public class Deck {
  [NotNull IEnumerable<Card> cards = new List<Cards>();
  [NotNull] public IEnumerable<Card> Cards { get; private set; }

  public void AddCard([NotNull] Card card) { cards.Add(card); }
  ...
}

public static IEnumerable<int> CardValuesOfColor(this Deck deck, Color color)
{
  var cards = deck.Cards;
  return cards.Where(c => c.Color == color).Select(c => c.Value);
}

在运行 ReSharper 代码检查时,它正确地抱怨“deck.Cards”处可能出现 System.NullReferenceException,因为此代码中的 deck 可能为 null。这是个好东西,我想保留它。

但是,它也会抱怨 c.Color 和 c.Value,因为它感觉 c 在这些情况下可能为空。这似乎太过分了,而且没有什么帮助。

我可以通过将 lambda 从“c.Color == color”更改为“c != null && c.Color == color”来“修复”c.Color,尽管这对于每个 Where 子句来说都很痛苦,尤其是当我从类设计中知道 deck.Cards 不会包含空值时。

这并不能解决 c.Value 问题,尽管很明显在修改了“where”子句之后,c 不可能为空。

似乎没有办法在不触发此警告的情况下编写 Select(...)、OrderBy(...) 等子句。

当我打开在我的项目中寻找可能的空引用时,我得到了数百个带有“问题”的文件。我们广泛使用 LINQ,这些“问题”中有很多(但不是全部)是虚假的,但不可能关闭。

我的选择似乎是关闭可能的空引用检查或在每次使用 LINQ 的 Select() 扩展时添加注释。这两种方法都不适合我。

有没有第三种选择可以解决这个问题?

【问题讨论】:

  • 我知道一个可枚举可以包含空项。在这种情况下,我知道它不会,通过类的构造。我首选的解决方案是有办法告诉 ReSharper,这样它就会知道。
  • 如何向“cards.Select(c => c.Value)”添加空检查? ReSharper 想要将整个语句(包括cards.Select() 调用本身)包装在一个 if 中,这根本行不通。
  • Alt+Enter 和 c (c|.Color) 之后的光标为您提供了一个上下文操作来生成正确的空检查
  • 不,它没有。至少不在 ReSharper 5.1 中。 Alt+Enter at c|.Color 提供了添加一个空检查,但它将整个 return 语句包装在一个 if (c != null) {...} 中,它 (a) 尝试在其范围之外访问 c , 和 (b) 添加不返回值的可能执行路径。
  • 那么有充分的理由升级到 v6 )

标签: linq resharper


【解决方案1】:

您必须记住,ReSharper 是一种静态代码分析工具,也就是说,它会查看您的代码中的模式而不考虑该代码的上下文,然后根据某人提出的“改进”或“修复”建议在 ReSharper(或者您自己,如果您自定义设置)认为“更好”。

静态分析的问题在于它没有关于代码意图的概念,因此您可以保证它有时会提出实际上使您的代码变得更糟的“改进”,因为它缺乏适合的上下文你的代码试图表达的意思。

这与“每条规则都有例外”的论点相同,使用 ReSharper 等工具的人(如我自己)不应盲目遵循这些建议。

在相关说明中:代码合同将帮助您解决问题

【讨论】:

    猜你喜欢
    • 2011-05-22
    • 1970-01-01
    • 2017-09-17
    • 2014-06-17
    • 2015-05-13
    • 1970-01-01
    • 2016-02-04
    • 2022-07-06
    • 2017-01-25
    相关资源
    最近更新 更多