32 votes

CA1001 implémente IDisposable sur la méthode async

Considérons le code suivant:

 public class Test
{
    public async Task Do()
    {
        await Task.Delay(200);

        using (var disposable = new Disposable())
        {
            disposable.Do();
        }
    }
}

public class Disposable : IDisposable
{
    public void Do()
    {
    }

    public void Dispose()
    {
    }
}
 

Lorsque j'exécute une analyse de code dans Visual studio, un avertissement s'affiche:

Avertissement CA1001 Implémenter IDisposable sur Test. <Do> d__0 car il crée des membres des types IDisposable suivants: 'Disposable'.

Pourquoi est-ce que je reçois ce message? La classe jetable est correctement mise au rebut et je ne la stocke nulle part.

En outre, cela semble convenir à l’analyseur:

 public class Test
{
    public void Do()
    {
        using (var disposable = new Disposable())
        {
            disposable.Do();
        }
    }
}
 

29voto

Evk Points 17804

C'est parce que le compilateur génère de l'état de la machine à partir de votre méthode asynchrone, et que l'état de la machine de la classe (nommé en <Do>d__0 dans ce cas) contient un champ de type Disposable , mais n'a pas lui-même implémente IDisposable interface. Il ne fait pas beaucoup de sens pour l'analyseur d'analyser généré par le compilateur de code (et c' <Do>d__0 classe est marquée avec CompilerGenerated d'attribut). Heureusement, il existe un paramètre pour l'analyseur de code pour éviter généré par le compilateur de code: accédez aux propriétés du projet, "Code de l'onglet" Analyse et cochez la case "Supprimer les résultats à partir de code généré", et cet avertissement va s'en aller.

10voto

Thomas Radioyes Points 139

Si vous examinez l'IL, vous constaterez qu'une classe <Do>d__0 est créée pour gérer les commandes asynchrones:

 // Nested Types
.class nested private auto ansi sealed beforefieldinit '<Do>d__0'
    extends [mscorlib]System.Object
    implements [mscorlib]System.Runtime.CompilerServices.IAsyncStateMachine
{
 

Plus tard, cette classe crée une instance de Disposable:

 IL_0074: newobj instance void ConsoleApp1.Disposable::.ctor()
 

C'est la classe qui déclenche CA1001 car CA1001 vérifie le IL, et la classe générée n'implémente pas IDisposable . Vous pouvez ignorer en toute sécurité l'avertissement CA1001 sur cette classe particulière.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X