使用 FluentAssertions NotBeNull 不会被可为 null 的分析器考虑

Mog*_*og0 13 c# fluent-assertions nullable-reference-types .net-5

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

Foo? foo = Bar();

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

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

我确实找到了这个,但我不知道如何在这种情况下使用它。

Gur*_*ron 0

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

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

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

foo.Should().NotBeNull()
    .And
    .Match<Foo>(f => f.Value == 5);
Run Code Online (Sandbox Code Playgroud)

或者使用BeEquivalentTo例如:

foo.Should().NotBeNull()
    .And
    .BeEquivalentTo(new Foo {Value = 5});
Run Code Online (Sandbox Code Playgroud)

请注意,BeEquivalentTo由于它比较对象的方法,有时使用起来相当麻烦:

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