.net 我在一个返回Task?的方法中得到了一个可能为空的引用的解引用,而调用一个返回Task?的方法

axzmvihb  于 2023-03-04  发布在  .NET
关注(0)|答案(2)|浏览(217)

下面的代码抛出一个错误
可能为空引用的解引用
在带有注解的行:

using System.Security.Cryptography.X509Certificates;

public class LowLevelClass
{ 
    public async Task? SomeMethod()
    {
        await Task.Run(() => Console.WriteLine("Hello"));
    }
}

public class TopLevelClass
{
    private LowLevelClass? lowLevelClass = null;

    public TopLevelClass()
    { 
        lowLevelClass = new LowLevelClass();
    }

    public async Task? SomeOtherMethod()
    {
        if(lowLevelClass != null)
            await lowLevelClass.SomeMethod(); // Dereference of possibly null reference
    }
}

public static class Program
{
    public static void Main()
    {
        TopLevelClass topLevelClass = new TopLevelClass();
        Task t = Task.Run(async () => await topLevelClass.SomeOtherMethod());
        t.Wait();
    }
}

我认为这是由于LowLevelClass.SomeMethod可能返回null Task
如何避免警告?
我尝试为lowLevelClass对象插入非空条件或将代码修改为

await lowLevelClass?.SomeMethod();

但没有成功

v1uwarro

v1uwarro1#

问题是你声明了SomeMethod()可以返回null,所以这是完全法律的的:

public Task? SomeMethod() => null;

所以当我们运行await lowLevelClass.SomeMethod();的时候,我们可能会运行await null,这是不法律的的,只要把签名改成public async Task SomeMethod()就可以了。
编译器不会试图猜测某个东西是否真的可以为空,至少不会在单个编译单元之外。如果声明返回值可以为空,那么就需要处理空值。

mwkjh3gx

mwkjh3gx2#

您可能希望您的lowlevel.SomeMethod()和顶级SomeOtherMethod()明确地返回Task。返回Task?从来没有一个好的理由,尤其是在async Task签名中。如果没有什么可做的,这些方法可以返回Task.CompletedTask
警告的获取与否可能取决于您的代码是否使用了最新版本的C#,并且是否启用了可空引用类型(看起来您已经启用了)。如果您启用了,您将获得更多“可能为空”的警告。但是不管是否有警告,我都不会使用async Task?

相关问题