Řešení upozornění souvisejících s using příkazy a using deklaracemi

Tento článek se zabývá následujícími chybami kompilátoru:

  • CS0245: Destruktory a object.Finalize nelze volat přímo. Zvažte volání IDisposable.Dispose, pokud je k dispozici.
  • CS0728: Pravděpodobně nesprávné přiřazení k místní proměnné, která je argumentem pro 'using' nebo podobný lock výraz. Volání Dispose nebo odemknutí se provede na původní hodnotě této místní proměnné.
  • CS1674: Typ použitý v příkazu using musí být implicitně konvertibilní na 'System.IDisposable'.
  • CS8410: Typ použitý v asynchronním using příkazu musí být implicitně konvertibilní naSystem.IAsyncDisposable "" nebo implementovat vhodnouDisposeAsync "" metodu.
  • CS8417: Typ použitý v asynchronním příkazu using musí implementovat 'System.IAsyncDisposable' nebo implementovat vhodnou 'DisposeAsync' metodu. Nemysleli jste 'using' místo 'await using'?
  • CS8418: Typ použitý v příkazu using musí implementovat 'System.IDisposable'. Mysleli jste spíše "await using' než "using"?
  • CS8647: Proměnná "using" nelze být použita přímo v rámci sekce "switch" (zvažte použití složených závorek).
  • CS8648: Po goto deklaraci using nelze přejít na místo.
  • CS8649: Nelze goto přejít na umístění před deklaraci using ve stejném bloku.
  • CS9229: Modifikátory nelze umístit na použití deklarací.

Implementace IDisposable a IAsyncDisposable

Následující chyby a upozornění kompilátoru označují problémy s implementací nebo použitím vzoru Dispose:

  • CS0245: Destruktory a object.Finalize nelze volat přímo. Zvažte volání IDisposable.Dispose, pokud je k dispozici.
  • CS1674: Typ použitý v příkazu using musí být implicitně konvertibilní na 'System.IDisposable'.
  • CS8410: Typ použitý v asynchronním using příkazu musí být implicitně převoditelný na 'System.IAsyncDisposable' nebo implementovat vhodnou metodu DisposeAsync.
  • CS8417: Typ použitý v asynchronním using příkazu musí implementovat "System.IAsyncDisposable' nebo implementovat vhodnouDisposeAsync '' metodu. Nemyslili jste 'using' místo 'await using'?
  • CS8418: Typ použitý v příkazu using musí implementovat 'System.IDisposable'. Nemyslili jste 'await using' místo 'using'?

Příkaz using zajistí řádné uvolnění zdrojů na konci bloku using. Pokud chcete použít typ s příkazem using , musí implementovat příslušné rozhraní pro odstranění. Pro synchronní using příkazy musí typ implementovat IDisposable. Pro asynchronní await using příkazy musí typ implementovat IAsyncDisposable.

  • Nelze volat přímo Finalize (CS0245): Přímo volat destruktor nebo metodu nelze. Garbage collector automaticky vyvolá finalizační metody, pokud už na objekty nebudou odkazy. Pro deterministické vyčištění implementujte IDisposable a místo toho volejte metodu Dispose .
  • Typ musí implementovat IDisposable (CS1674): Pouze typy, které implementují IDisposable, mohou být použity v using příkazu. Typy hodnot neimplementují toto rozhraní a parametry obecného typu bez správných omezení nelze předpokládat, že budou uvolnitelné. Použijte omezení typu, jako je where T : IDisposable, při práci s generickými typy.
  • Typ musí implementovat IAsyncDisposable (CS8410):: Typy používané s await using musí implementovat IAsyncDisposable nebo poskytnout vhodnou DisposeAsync metodu. Pokud váš typ nepodporuje asynchronní odstranění, použijte místo toho synchronní using příkaz nebo implementujte požadované rozhraní.
  • Neshodný model odstranění (CS8417, CS8418): CS8417 nastane při použití await using s typem, který implementuje IDisposablepouze . CS8418 nastane, když používáte synchronní using s typem, který implementuje pouze IAsyncDisposable. Přiřaďte klíčové slovo k rozhraní, které váš typ implementuje, nebo implementujte obě rozhraní, pokud potřebujete podporovat oba vzory.

Další informace naleznete v tématu Finalizers, Implement a Dispose metodu a Implement a DisposeAsync metodu.

Použití rozsahu proměnných a řídicího toku

Následující chyby a upozornění kompilátoru se vztahují k nesprávnému použití proměnných using v rámci příkazů toku řízení:

  • CS0728: Pravděpodobné nesprávné přiřazení místní proměnné, která je argumentem k using nebo lock příkazu. Volání Dispose nebo odemknutí proběhne na původní hodnotě lokální proměnné.
  • CS8647: Proměnnou s použitím nelze přímo použít v sekci přepínače (zvažte použití složených závorek).
  • CS8648: Po goto deklaraci using nelze přejít na místo.
  • CS8649: Nelze přejít na umístění před deklarací 'using' ve stejném bloku.

Proměnné deklarované s using mají specifická pravidla rozsahu, která zabraňují úniku prostředků. Kompilátor vynucuje tato pravidla, aby zajistil správné odstranění.

  • Přiřazení k použití proměnné (CS0728):: Toto upozornění indikuje, že jste proměnné, která je prostředkem using v příkazu, přiřadili novou hodnotu. Volání dispose se provádí na původní hodnotě, nikoli na nově přiřazené hodnotě, což může vést k úniku prostředků. Inicializujte prostředek v deklaraci příkazu using místo jeho pozdějšího přiřazení.

  • Použití proměnné v oddílu switch (CS8647): Deklarace using vytvoří proměnnou, která je uvolněna na konci svého rozsahu. Při použití přímo v části přepínače bez závorek je oblast nejednoznačná a může vést k chybám. Přikryjte obsah části spínače složenými závorkami k jednoznačnému definování rozsahu.

  • Příkazy Goto a použití deklarací (CS8648, CS8649): Nelze použít goto příkazy ke skákání přes using deklarace, protože by to přeskočilo správnou správu prostředků. CS8648 nastane při skoku vpřed nad using deklaraci a CS8649 nastane při přeskakování dozadu na místo před using deklaraci. Restrukturalizujte svůj kód tak, aby používal strukturovaný tok řízení, jako jsou smyčky, nebo přesuňte deklaraci using mimo skokový cíl.

Další informace najdete v příkazu using.

Nesprávná using deklarace

  • CS9229: Modifikátory nelze umístit na deklarace using.

Deklarace proměnné zabalená v using deklaraci nemůže obsahovat žádný z následujících modifikátorů:

  • const
  • static
  • volatile
  • readonly
  • Modifikátory přístupnosti: public, protected, internal, private, protected internal, nebo private protected

Následující příklad generuje 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() { }
}

Chcete-li tuto chybu opravit, odeberte modifikátor z using deklarace:

using var resource = new Resource();

Další informace najdete v příkazu using.