是否可以在基类上有虚拟异步方法
本文关键字:虚拟 异步方法 基类 是否 | 更新日期: 2023-09-27 18:15:30
我正在处理一些代码,其中我有2个具有非常相似逻辑和代码的类。我在两个类上都有protected async void LoadDataAsync()
方法。
目前我正在重构它,并考虑将共享逻辑移动到基类。
在基类上有virtual async
方法并在派生类上重写它是可以的吗?
有什么问题吗?
我的代码是这样的:
public class Base
{
protected virtual async void LoadDataAsync() {}
}
public class Derived : Base
{
protected override async void LoadDataAsync()
{
// awaiting something
}
}
类似(但不相同)的问题已经问过了。
简短回答
-
virtual
方法可以将标记为async
- 不能将
abstract
方法标记为async
这样做的原因是async
实际上不是方法签名的一部分。它只是告诉编译器如何处理方法体本身的编译(不适用于重写方法)。由于抽象方法没有方法体,所以应用async
修饰符是没有意义的。
长回答
如果基类提供了方法的默认实现,但不需要做任何工作,我建议使用以下方法,而不是基类中的当前签名。
protected virtual Task LoadDataAsync() {
return Task.CompletedTask;
}
实现中的关键更改如下:
- 将返回值从
void
更改为Task
(记住async
实际上不是返回类型的一部分)。与返回void
不同,当返回Task
时,调用代码可以执行以下任何操作:
- 等待操作完成
- 查看任务状态(已完成、取消、故障)
- 避免使用
async
修饰符,因为该方法不需要await
任何内容。相反,只需返回一个已经完成的Task
实例。如果需要,覆盖此方法的方法仍然可以使用async
修饰符。 是的,这很好,但你应该使用async Task
而不是async void
。我有一篇MSDN文章解释了为什么
同意@Sam。
我抛出异常只是为了确保实际的逻辑被实现。更符合我的要求,就这样。
protected virtual Task LoadDataAsync()
{
throw new NotImplementedException();
}