【问题标题】:Using FluentAssertions NotBeNull isn't taken into account by nullable analysers可空分析器不考虑使用 FluentAssertions NotBeNull
【发布时间】:2021-11-15 20:30:13
【问题描述】:

当我使用 Fluent 断言来测试一个属性是否不为空时,分析器仍然会抱怨后续行将该行取消引用为可能为空。在使用 FluentAssertions 进行测试后,有什么方法可以让编译器将属性识别为不为空? 例如

Foo? foo = Bar();

foo.Should().NotBeNull();
foo.Value.Should().Be(5); // Warning about dereference of a possibly null reference on this line

我知道我可以使用 !在第二行的 foo 上,但有什么方法可以让分析器自己解决这个问题?

我确实找到了this,但我看不出在这种情况下如何使用它。

【问题讨论】:

    标签: c# .net-5 fluent-assertions nullable-reference-types


    【解决方案1】:

    您可以编写自己的替代扩展方法:

    public static void ShouldNotBeNull<T>([NotNull] this T? value)
    {
      // throw if null
    }
    

    【讨论】:

      【解决方案2】:

      您在这里无能为力(除了在 github 上提出问题,如this 评论中提到的问题,或this 可空值类型的问题)。使用MemberNotNullWhenAttribute,即使您可以访问源代码并编译您的版本,恐怕也不会在这里做太多事情,因为foo 不是AndConstraint 的成员,由NotBeNull 返回。

      因此,您可以选择在这里使用! 或链接断言,这有点麻烦,因为FluentAssertions 由于某种原因会丢失类型信息或编写您自己的方法来封装此检查。

      对于链接断言选项,您可以执行以下操作:

      foo.Should().NotBeNull()
          .And
          .Match<Foo>(f => f.Value == 5);
      

      或以BeEquivalentTo 为例:

      foo.Should().NotBeNull()
          .And
          .BeEquivalentTo(new Foo {Value = 5});
      

      请注意,BeEquivalentTo 有时使用起来也很麻烦,因为它比较对象的方法:

      当两个对象图具有相同名称且具有相同值的属性时,对象是等效的,而与这些对象的类型无关。如果一种类型可以转换为另一种类型并且结果相等,则两个属性也相等。只要集合实现了IEnumerable&lt;T&gt; 并且集合中的所有项目在结构上相同,就会忽略集合属性的类型。

      【讨论】:

        猜你喜欢
        • 2018-08-03
        • 2017-01-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-08-26
        • 2020-10-18
        相关资源
        最近更新 更多