异步元组返回是否有等效的 NotNullWhen C# 模式?

Mat*_*day 9 c# nullable async-await

在具有可空类型的 C# 中,可以实现智能地进行空检查的“TryGet”,例如,

bool TryGetById(int id, [NotNullWhen(returnValue: true)] out MyThing? myThing)
Run Code Online (Sandbox Code Playgroud)

这允许调用者跳过对 out var myThing 的 null 检查。

不幸的是,异步不允许输出参数,并且使用元组返回的模式不允许这种智能的 NotNull 检查(至少,据我所知)。还有其他选择吗?

有没有办法在异步元组返回类型上使用“NotNullWhen”等效项,例如,

Task<(bool Ok, [NotNullWhen(returnValue: true)] MyThing? MyThing)> TryGetById(int id)
Run Code Online (Sandbox Code Playgroud)

AAA*_*ddd 8

目前还没有针对值元组的实现。然而!从C#9您可以使用 来滚动您自己的 struct(甚至更好的C#10 记录structMemberNotNullWhen

MemberNotNullWhenAttribute 类

指定方法或属性将确保在以指定的返回值条件返回时列出的字段和属性成员具有非空值。

注意:您将需要重新实现所有 tupley 的优点,例如平等等。

世界上最做作的例子随之而来

#nullable enable

public readonly struct Test
{
   [MemberNotNullWhen(returnValue: true, member: nameof(Value))]
   public bool IsGood => Value != null;

   public string? Value { get; init; }
}

public static Task<Test> TryGetAsync()
   => Task.FromResult(new Test {Value = "bob"});

public static void TestMethod(string bob)
   => Console.WriteLine(bob);
Run Code Online (Sandbox Code Playgroud)

用法

var result = await TryGetAsync();
if (result.IsGood)
   TestMethod(result.Value); // <= no warning
Run Code Online (Sandbox Code Playgroud)