Подтвердить что ты не робот

Можно ли использовать виртуальный метод async для базового класса?

Я работаю с некоторым кодом, где у меня есть 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
   }
}

Этот вопрос уже задан (но не тот же).

4b9b3361

Ответ 1

Короткий ответ

  • Метод virtual может быть помечен как async
  • Метод abstract не может быть помечен как async

Причиной этого является async, фактически не являющийся частью сигнатуры метода. Он просто сообщает компилятору, как обрабатывать компиляцию самого тела метода (и не относится к переопределяющим методам). Поскольку абстрактный метод не имеет тела метода, нет смысла применять модификатор async.

Длинный ответ

Вместо вашей текущей подписи в базовом классе я бы рекомендовал следующее, если базовый класс предоставляет стандартную реализацию метода, но не нуждается в какой-либо работе.

protected virtual Task LoadDataAsync() {
  return Task.FromResult(default(object));
}

Ключевыми изменениями в вашей реализации являются следующие:

  • Измените возвращаемое значение с void на Task (помните, что async на самом деле не является частью возвращаемого типа). В отличие от возвращаемого void, когда возвращается Task, вызывающий код имеет возможность выполнить одно из следующих действий:
    • Дождитесь завершения операции
    • Проверить статус задачи (завершена, отменена, сбой)
  • Избегайте использования модификатора async, поскольку для метода не требуется await ничего. Вместо этого просто верните уже завершенный экземпляр Task. Методы, которые переопределяют этот метод, по-прежнему смогут использовать модификатор async, если он ему нужен.