虚拟方法缺少 'await' 返回值?

3

我有一个异步的虚拟方法,返回一个默认的布尔值,用于我的应用程序的基本功能。例如,如果没有需要设置的内容,就假设它成功了。

我理解非虚拟方法中的警告方法,但我想知道在虚拟方法中实现这个的最佳方式是什么。我应该在虚拟方法中返回什么来确保去除这个警告?或者我应该忽略它?

// WARNING: This async method lacks 'await'
// virtual is the differentiating factor here
protected virtual async Task<bool> SetupAsync()
{
    return true;
}

5
"virtual"与此无关。你将你的方法标记为“async”但是却没有使用任何地方的“await”。 - madreflection
2
可能是重复的问题:此异步方法缺乏 'await' 运算符,将以同步方式运行 - madreflection
我理解,我的问题特别指出了这是一个“虚拟”方法。当其虚拟实现为非异步时,我无法将此方法覆盖为异步。我正在询问在需要默认简单布尔返回时,在虚拟方法中返回什么是最佳实践。 - David Owens
重写的方法不必是 async,只需要可等待。移除 async 并返回 Task.FromResult(true) - madreflection
那么 protected virtual Task<bool> SetupAsync() 不需要任何重写方法在其签名中加上 async 吗? - David Owens
1个回答

8

我理解您正在创建一个预计会被覆盖的类,并且希望为SetupAsync()提供默认实现,以允许覆盖版本成为async

async关键字不是必须复制以使方法可被覆盖的方法签名的一部分。只有返回类型、参数和访问修饰符。

如果您的方法中没有异步代码,则不要使用async。如果您想允许覆盖版本成为async,那么您所需要做的就是使它返回一个Task

在您的默认实现(同步运行)中,您只需使用Task.FromResultTask中返回一个值。

例如:

class Test {
    protected virtual Task<bool> SetupAsync() {
        return Task.FromResult(true);
    }
}

class Test2 : Test {
    protected override async Task<bool> SetupAsync() {
        await Task.Delay(1000);
        return false;
    }
}

覆盖方法并不涉及方法的内部工作原理,而是涉及它如何向其他代码公开。任何代码都必须能够以与默认实现相同的方式调用覆盖的方法,而async关键字本身与此无关。

async关键字只是在方法内部启用了await的使用。确实,使用async关键字需要该方法返回一个Task,但是它返回Task的事实是改变了其他代码与其交互的方式。


谢谢,这正好描述了我的用例。覆盖签名中包含的内容的选择性是有趣的... - David Owens
1
我在我的答案中添加了一些额外的内容,希望能够解释那种“选择性质”。 - Gabriel Luci
太好了,我知道使用async可以启用await的使用,但我的理解出现了偏差:如果在virtual签名中没有使用async,那么我将失去在重写方法中使用await的能力。 - David Owens

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接