Partager via


Résoudre les avertissements liés aux instructions using et aux déclarations using

Cet article traite des erreurs suivantes du compilateur :

  • CS0245 : Les destructeurs et object.Finalize ne peuvent pas être appelés directement. Essayez d’appeler IDisposable.Dispose le cas échéant.
  • CS0728 : Affectation éventuellement incorrecte à une variable locale, qui est l’argument d’une instruction using ou lock. L’appel Dispose ou le déverrouillage se produira sur la valeur d’origine de la variable locale.
  • CS1674 : Le type utilisé dans une instruction using doit être implicitement convertible en 'System.IDisposable'.
  • CS8410 : « Le type utilisé dans une instruction asynchrone using doit être implicitement convertible en «System.IAsyncDisposable » ou implémenter une méthode «DisposeAsync » appropriée.
  • CS8417 : Le type utilisé dans une instruction using asynchrone doit implémenter 'System.IAsyncDisposable' ou implémenter une méthode 'DisposeAsync' appropriée. Avez-vous dit «using » plutôt que «await using ? » ?
  • CS8418 : Le type utilisé dans une instruction using doit implémenter 'System.IDisposable'. Avez-vous dit «await using plutôt que « using » ?
  • CS8647 : Une variable using ne peut pas être utilisée directement dans une section switch (envisagez d’utiliser des accolades).
  • CS8648 : Un goto ne peut pas sauter à un emplacement après une déclaration using.
  • CS8649 : Il est impossible de se diriger vers une localisation avant une déclaration « using » dans le même bloc.
  • CS9229 : Les modificateurs ne peuvent pas être placés à l’aide de déclarations.

Implémentation d’IDisposable et IAsyncDisposable

Les erreurs et avertissements du compilateur suivants indiquent des problèmes liés à l’implémentation ou à l’utilisation du modèle de suppression :

  • CS0245 : Destructeurs et object.Finalize ne peuvent pas être appelés directement. Envisagez d’appeler IDisposable.Dispose si disponible.
  • CS1674 : Le type utilisé dans une instruction using doit être implicitement convertible en 'System.IDisposable'.
  • CS8410 : Le type utilisé dans une instruction asynchrone using doit être implicitement convertible en 'System.IAsyncDisposable' ou implémenter une méthode « DisposeAsync » appropriée.
  • CS8417 : Le type utilisé dans une instruction asynchrone using doit implémenter 'System.IAsyncDisposable' ou implémenter une méthode 'DisposeAsync' appropriée. Avez-vous dit «using » plutôt que «await using ? » ?
  • CS8418 : Le type utilisé dans une instruction using doit implémenter 'System.IDisposable'. Avez-vous dit «await using » plutôt que «using ? » ?

L’instruction using garantit l’élimination appropriée des ressources à la fin du using bloc. Pour utiliser un type avec une using instruction, il doit implémenter l’interface de suppression appropriée. Pour les instructions synchrones using , le type doit implémenter IDisposable. Pour les instructions asynchrones await using , le type doit implémenter IAsyncDisposable.

  • Impossible d’appeler Finalise directement (CS0245) : vous ne pouvez pas appeler directement un destructeur ou la Object.Finalize méthode. Le ramasse-miettes appelle automatiquement les finaliseurs lorsque les objets ne sont plus référencés. Pour un nettoyage déterministe, implémentez IDisposable et appelez la méthode Dispose à la place.
  • Le type doit implémenter IDisposable (CS1674) : seuls les types qui implémentent IDisposable peuvent être utilisés dans une using instruction. Les types valeur n’implémentent pas cette interface et les paramètres de type générique sans contraintes appropriées ne peuvent pas être supposés être jetables. Appliquez une contrainte de type comme where T : IDisposable lors de l’utilisation de types génériques.
  • Type doit implémenter IAsyncDisposable (CS8410) : les types utilisés avec await using doivent implémenter IAsyncDisposable ou fournir une méthode appropriée DisposeAsync . Si votre type ne prend pas en charge la suppression asynchrone, utilisez plutôt une instruction synchrone using ou implémentez l’interface requise.
  • Modèle d’élimination incompatible (CS8417, CS8418) : CS8417 se produit lorsque vous utilisez await using avec un type qui n’implémente que IDisposable. CS8418 se produit lorsque vous utilisez la synchronisation using avec un type qui implémente IAsyncDisposableuniquement . Faites correspondre le using mot clé à l’interface que votre type implémente, ou implémentez les deux interfaces si vous devez prendre en charge les deux modèles.

Pour plus d’informations, consultez Finaliseurs, Implémenter une méthode Dispose et Implémenter une méthode DisposeAsync.

Utilisation d’une étendue variable et d’un flux de contrôle

Les erreurs et avertissements du compilateur suivants concernent une utilisation incorrecte des using variables dans les instructions de contrôle de flux :

  • CS0728 : Assignation éventuellement incorrecte à la variable locale, qui est l’argument d’une instruction using ou d’une instruction lock. L’appel Dispose ou le déverrouillage se produira sur la valeur d’origine de la variable locale.
  • CS8647 : Une variable utilisant ne peut pas être utilisée directement dans une section switch (envisagez d’utiliser des accolades).
  • CS8648 : On ne peut pas sauter à un emplacement après une déclaration d'utilisation.
  • CS8649 : Il est impossible goto de passer à un emplacement avant une déclaration using dans le même bloc.

Les variables déclarées avec using ont des règles d’étendue spécifiques qui empêchent les fuites de ressources. Le compilateur applique ces règles pour garantir une suppression appropriée.

  • Affectation à l’utilisation de la variable (CS0728) : cet avertissement indique que vous avez affecté une nouvelle valeur à une variable qui est la ressource dans une using instruction. L’appel de suppression se produit sur la valeur d’origine, et non sur la valeur nouvellement attribuée, ce qui peut entraîner des fuites de ressources. Initialisez la ressource dans la using déclaration d’instruction au lieu de l’affecter ultérieurement.

  • Utilisation de la variable dans la section switch (CS8647) : une using déclaration crée une variable qui est libérée à la fin de son étendue. Lorsqu'on l'utilise directement dans un bloc de switch sans accolades, l'étendue est ambiguë et peut entraîner des erreurs. Enveloppez le contenu de la section 'switch' dans les accolades pour définir clairement l’étendue.

  • Instructions Goto et utilisation de déclarations (CS8648, CS8649) : vous ne pouvez pas utiliser goto d’instructions pour sauter sur using les déclarations, car le saut ignore la gestion des ressources appropriée. CS8648 se produit lors d’un saut vers l’avant sur une using déclaration, et CS8649 se produit lors d’un saut vers l’arrière à un emplacement avant une using déclaration. Restructurez votre code pour utiliser un flux de contrôle structuré tel que des boucles ou déplacer la using déclaration en dehors de la cible de rebond.

Pour plus d’informations, consultez l’instruction using.

Déclaration incorrecte using

  • CS9229 : Les modificateurs ne peuvent pas être placés à l’aide de déclarations.

Une déclaration de variable encapsulée dans une using déclaration ne peut inclure aucun des modificateurs suivants :

  • const
  • static
  • volatile
  • readonly
  • Modificateurs d’accessibilité : public, , protectedinternal, private, protected internalouprivate protected

L’exemple suivant génère l’erreur CS9229 :

using System;

class Program
{
    static void Main()
    {
        // error CS9229: Modifiers cannot be placed on using declarations.
        public using var resource = new Resource();

        // error CS9229: Modifiers cannot be placed on using declarations.
        static using var anotherResource = new Resource();
    }
}

class Resource : IDisposable
{
    public void Dispose() { }
}

Pour corriger cette erreur, supprimez le modificateur de la using déclaration :

using var resource = new Resource();

Pour plus d’informations, consultez l'instruction 'using'.