Je travaille avec du code, où j'ai 2 classes avec une logique et un code très similaires. J'ai la méthode protected async void LoadDataAsync()
sur les deux classes.
Actuellement, je le refactorise et je pense à déplacer la logique partagée vers la classe de base.
Est-il OK d'avoir virtual async
méthode sur la classe de base et la remplacer sur les classes dérivées?
Y a-t-il des problèmes avec cela?
Mon code ressemble à ceci:
public class Base
{
protected virtual async void LoadDataAsync() {}
}
public class Derived : Base
{
protected override async void LoadDataAsync()
{
// awaiting something
}
}
Similaire (mais pas le même) la question a déjà été posée.
virtual
peut être marquée comme async
abstract
ne peut pas être marquée comme async
La raison en est que async
ne fait pas réellement partie de la signature de la méthode. Il indique simplement au compilateur comment gérer la compilation du corps de la méthode lui-même (et ne s'applique pas aux méthodes de substitution). Puisqu'une méthode abstraite n'a pas de corps de méthode, il n'est pas logique d'appliquer le modificateur async
.
Plutôt que votre signature actuelle dans la classe de base, je recommanderais ce qui suit si la classe de base fournit une implémentation par défaut de la méthode mais n'a pas besoin de faire de travail.
protected virtual Task LoadDataAsync() {
return Task.FromResult(default(object));
}
Les principaux changements par rapport à votre implémentation sont les suivants:
void
en Task
(rappelez-vous que async
ne fait pas réellement partie du type de retour). Contrairement au renvoi de void
, lorsqu'un Task
est renvoyé, le code appelant peut effectuer l'une des opérations suivantes: async
, car la méthode n'a pas besoin de await
quoi que ce soit. À la place, renvoyez simplement une instance Task
déjà terminée. Les méthodes qui remplacent cette méthode pourront toujours utiliser le modificateur async
si elles en ont besoin.Oui, ça va, mais vous devez utiliser async Task
au lieu de async void
. J'ai un article MSDN qui explique pourquoi .