次の方法で共有


using ステートメントとusing宣言に関連する警告を解決する

この記事では、次のコンパイラ エラーについて説明します。

  • CS0245: デストラクターと object.Finalize を直接呼び出すことはできません。使用可能な場合は、 IDisposable.Dispose の呼び出しを検討してください。
  • CS0728: using ステートメントまたは lock ステートメントの引数であるローカル変数への代入が正しくない可能性があります。 Dispose 呼び出しまたはロック解除は、ローカルの元の値で行われます。
  • CS1674: using ステートメントで使用される型は、暗黙的に 'System.IDisposable' に変換できる必要があります。
  • CS8410: '非同期 using ステートメントで使用される型は、暗黙的に 'System.IAsyncDisposable' に変換可能であるか、適切な 'DisposeAsync' メソッドを実装する必要があります。
  • CS8417: 非同期 using ステートメントで使用される型は、'System.IAsyncDisposable' を実装するか、適切な 'DisposeAsync' メソッドを実装する必要があります。"using" ではなく "await using" を意味しましたか?
  • CS8418: using ステートメントで使用される型は、'System.IDisposable' を実装する必要があります。"使用" ではなく "await using" を意味しましたか?
  • CS8647: 使用中の変数は switch セクション内で直接使用できません(中かっこの使用を検討してください)。
  • CS8648: gotoは、using 宣言の後の場所にジャンプできません。
  • CS8649: gotoは、同じブロック内の using 宣言の前の場所にジャンプできません。
  • CS9229: 修飾子を使用宣言に付与することはできません。

IDisposable と IAsyncDisposable の実装

次のコンパイラ エラーと警告は、dispose パターンの実装または使用に関する問題を示しています。

  • CS0245: デストラクターと object.Finalize を直接呼び出すことはできません。使用可能な場合は、 IDisposable.Dispose の呼び出しを検討してください。
  • CS1674: using ステートメントで使用される型は、'System.IDisposable' に暗黙的に変換できる必要があります。
  • CS8410: 非同期 using ステートメントで使用される型は、暗黙的に 'System.IAsyncDisposable' に変換するか、適切な 'DisposeAsync' メソッドを実装する必要があります。
  • CS8417: 非同期using ステートメントで使用される型は、'System.IAsyncDisposable' を実装するか、適切な 'DisposeAsync' メソッドを実装する必要があります。"using" ではなく "await using" を意味しましたか?
  • CS8418: using ステートメントで使用される型は、'System.IDisposable' を実装する必要があります。"'await using' の代わりに 'using' を意図していましたか?"

using ステートメントを使用すると、using ブロックの最後にリソースが適切に破棄されます。 using ステートメントで型を使用するには、適切な破棄インターフェイスを実装する必要があります。 同期 using ステートメントの場合、型は IDisposableを実装する必要があります。 非同期 await using ステートメントの場合、型は IAsyncDisposableを実装する必要があります。

  • Finalize を直接呼び出すことはできません (CS0245):デストラクターまたは Object.Finalize メソッドを直接呼び出すことはできません。 オブジェクトが参照されなくなったときに、ガベージ コレクターによってファイナライザーが自動的に呼び出されます。 確定的なクリーンアップを行う場合は、 IDisposable を実装し、代わりに Dispose メソッドを呼び出します。
  • 型は IDisposable (CS1674) を実装する必要があります: IDisposable を実装する型のみを using ステートメントで使用できます。 値型はこのインターフェイスを実装せず、適切な制約のないジェネリック型パラメーターは破棄可能と見なすことはできません。 ジェネリック型を使用する場合は、 where T : IDisposable のような型制約を適用します。
  • 型は IAsyncDisposable (CS8410) を実装する必要があります。 await using で使用される型は、 IAsyncDisposable を実装するか、適切な DisposeAsync メソッドを提供する必要があります。 型が非同期破棄をサポートしていない場合は、代わりに同期 using ステートメントを使用するか、必要なインターフェイスを実装します。
  • 破棄パターンの不一致 (CS8417、CS8418): await usingのみを実装する型でIDisposableを使用すると、CS8417 が発生します。 CS8418 は、usingのみを実装する型で同期IAsyncDisposableを使用する場合に発生します。 using キーワードを型が実装するインターフェイスと一致させるか、両方のパターンをサポートする必要がある場合は両方のインターフェイスを実装します。

詳細については、「 ファイナライザー」、 「Dispose メソッドを実装する」、および 「DisposeAsync メソッドを実装する」を参照してください。

変数スコープと制御フローの使用

次のコンパイラ エラーと警告は、制御フロー ステートメント内での using 変数の不適切な使用に関連しています。

  • CS0728: using または lock ステートメントの引数であるローカル変数への代入が正しくない可能性があります。Dispose呼び出しまたはロック解除は、ローカルの元の値で行われます。
  • CS8647: using変数をswitch節内で直接使用することはできません (中かっこの使用を検討してください)。
  • CS8648: gotoは、using 宣言の後の場所にジャンプできません。
  • CS8649: gotoは、同じブロック内の using 宣言の前の場所にジャンプできません。

usingで宣言された変数には、リソース リークを防ぐ特定のスコープ規則があります。 コンパイラは、適切な破棄を保証するために、これらの規則を適用します。

  • using 変数への代入 (CS0728): この警告は、using ステートメント内でリソースとして扱われる変数に新しい値を割り当てたことを示します。 dispose 呼び出しは、新しく割り当てられた値ではなく、元の値で発生し、リソース リークにつながる可能性があります。 後で割り当てるのではなく、 using ステートメント宣言でリソースを初期化します。

  • switch セクションでの変数の使用 (CS8647):using宣言では、スコープの末尾に破棄される変数が作成されます。 中かっこのないスイッチ セクションで直接使用すると、スコープがあいまいになり、エラーが発生する可能性があります。 スイッチセクションの内容をブロックで囲んで、範囲を明確に定義します。

  • Goto ステートメントと宣言の使用 (CS8648、CS8649): ジャンプでは適切なリソース管理がスキップされるため、 goto ステートメントを使用して using 宣言をジャンプすることはできません。 CS8648 は、 using 宣言を前方にジャンプするときに発生し、CS8649 は、 using 宣言の前の場所に戻るときに発生します。 ループなどの構造化された制御フローを使用するようにコードを再構築するか、ジャンプ ターゲットの外側に using 宣言を移動します。

詳細については、 using ステートメントを参照してください。

正しくない using 宣言

  • CS9229: 修飾子をusing宣言に付けることはできません。

using宣言でラップされた変数宣言には、次の修飾子を含めることはできません。

  • const
  • static
  • volatile
  • readonly
  • アクセシビリティ修飾子: publicprotectedinternalprivateprotected internal、または private protected

次の例では 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() { }
}

このエラーを修正するには、 using 宣言から修飾子を削除します。

using var resource = new Resource();

詳細については、 using ステートメントを参照してください。