web-dev-qa-db-ja.com

Visual Studioで使い捨てオブジェクトを認識しますか?

IDisposableオブジェクトは、usingステートメントまたはDispose()メソッドを呼び出すことによって破棄することをお勧めします。オブジェクトがVisual Studioで使い捨て可能かどうかを調べるのは直感的ではないことがわかりました。

私の質問は、VSでIDisposableオブジェクトを認識する方法はありますか?

23
T D Nguyen

VSで使い捨てオブジェクトを別の方法で強調表示したい場合は、この post を確認してください。私は常にR#を使用しているので、個人的にはResharper answer を好みます。

オブジェクトがインターフェイスのインスタンスであるかどうかを確認するだけの場合は、変数名とNavigate -> Object BrowserまたはGo to Declarationを右クリックして、クラス名Go to Definition/Peek Definitionを右クリックします。

enter image description here

Peek Definitionは、必要なすべてをインラインで表示するので、気に入っていただけるでしょう。

enter image description here

Dispose()メソッドがある場合、99.9%が使い捨てオブジェクトであることを確認できます。メソッドに悪い名前を付ける人のためにこれを0.01%与えます:)。

29
Andrei

まだ誰もこれについて言及していないことに私は驚いています。 Visual Studioのエディション がサポートしている場合は、ビルドで Code Analysis をオンにすることをお勧めします。

それが完了したら、少なくとも CA20 (スコープを失う前にオブジェクトを破棄)、 CA221 (破棄可能なフィールドは破棄)および CA2202 (オブジェクトを複数回破棄しない)ルールがカバーされています。このようにして、使い捨てオブジェクトを正しく処理していない場合、コンパイラはshoutを実行する必要があります。

(ただし、コンパイラーにnotフラグを設定すると、多くのStackOverflowの質問が証明できるように、使い捨てオブジェクトの一部の使用法がより大きな課題になる可能性があります)

14

オブジェクトブラウザを使用して、実装されたインターフェイスでクラス継承階層を表示できます

enter image description here

8
Aleksey L.

完全を期すために、コードでそれをチェックする方法を尋ねずに、型がIDisposableのようなインターフェイスを実装しているかどうかをどこで確認できるかを知りたい場合は、いつでも確認できます- [〜#〜] msdn [〜#〜]

FileStream

  • それは備考セクションですでに述べられています:

このタイプは、IDisposableインターフェースを実装します。タイプの使用が終了したら、直接または間接的に破棄する必要があります。タイプを直接破棄するには、try/catchブロックでそのDisposeメソッドを呼び出します。間接的に破棄するには、using(C#の場合)やUsing(Visual Basicの場合)などの言語構成体を使用します。詳細については、IDisposableインターフェイストピックの「IDisposableを実装するオブジェクトの使用」セクションを参照してください。

  • または Dispose method を検索します。そこで、このクラスまたは親クラスがIDispableを実装しているかどうかを確認できます。この場合、それは Stream から継承されます。これは、クラス構文と注釈セクションで言及されているそのインターフェースを実装します。

    public abstract class Stream : MarshalByRefObject, IDisposable
    

Visual Studioでインターフェイスの実装を見つける方法を知りたい場合は、次の質問にすでに回答しています。

インターフェイスのすべての実装をどのように見つけますか?

6
Tim Schmelter

クラスが実装するインターフェイスと、それが公開されているすべてのフィールド、プロパティ、メソッドなどを確認する方法は、コードでそのクラスに移動することです。例えば:

_Image image = Image.FromFile(path);
_

インスタンスではなくクラスをクリックし、F12キーを押してください。これにより、そのクラスのメタデータファイルが表示されます。例:_Image.cs_ファイルには、上記のクラス宣言が含まれています。

_public abstract class Image : MarshalByRefObject, ISerializable, ICloneable, IDisposable
_

その後、F12を使用して、クリックして他のクラスに移動することもできます。これらのクラスは通常、Visual Studioでは水色で表示されることに注意してください。

Screenshot showing light blue colours.

クラスを右クリックし、ドロップダウンリストから[定義に移動]を選択して、このメタデータファイルにアクセスすることもできます。


理想的ではありませんが、クラスのインスタンスに移動して、最後に_._を置くこともできます。これによりインテリセンスが表示され、アイテムがインターフェイスを実装している場合は、リストにDispsose()が表示されます。

また、単にmyInstance.Dispose();またはusing (myInstance = new MyClass()) {}と書くこともできます。それがクラスをコンパイルする場合、インターフェースを実装し、それ以外の場合はインターフェースを実装しません。

5
TheLethalCoder

Resharperとその同類のシェルアウトの(愚かな?)代替手段として、Visual StudioにはExternal Tools([ツール]メニュー)の概念があります。あなたは(ab)使用して次のようなことをすることができます:

  • タイトル: _Is Disposa&ble_
  • コマンド: _C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe_
  • 引数:-Command "&{$i=[Type]::GetType('System.IDisposable');[AppDomain]::CurrentDomain.GetAssemblies()|%{ $_.GetTypes()}|?{$_.FullName.EndsWith('.$(CurText)')}|%{New-Object PSObject -Property @{'Type'=$_;'IDisposable'=$i.IsAssignableFrom($_)}}|ft}"
  • 出力ウィンドウを使用:チェック済み

これは、エディターで選択した文字列を読み取り、その文字列を名前として.NETタイプを検索し、その文字列がIDisposableを実装しているかどうかについてTrue/Falseを表示します。

ツールのPowershellコマンドは、可能性を示すために私が実行できるquickestアプローチにすぎませんが、完全には程遠いです-型を見つけるだけですPowershellがデフォルトでロードするアセンブリ。アイデアを拡張したい場合は、プロジェクトをロードし、プロジェクトがロードしたすべてのアセンブリをスキャンするコマンドライン.NETアプリを作成できます。

たとえば、コードでWord Streamを強調表示して、外部ツール(ALT+TALT+B 例では)、次のように返されます。

タイプIDisposable 
 ---- ----------- 
 System.IO.Stream True

Powershellコマンドを分解するには:

_&{ $i=[Type]::GetType('System.IDisposable');        # Get the IDisposable interface
   [AppDomain]::CurrentDomain.GetAssemblies() `     # Get all loaded assemblies
    | %{ $_.GetTypes() } `                          # For each Assembly, get all types
    | ?{ $_.FullName.EndsWith('.$(CurText)') } `    # Filter types that are named $(CurText) - $(CurText) is a macro within VS External Tools
    | %{ New-Object PSObject -Property @{           # For each type, return an object containing...
         'Type' = $_;                               # ...the type name...
         'IDisposable' = $i.IsAssignableFrom($_)    # ...and whether the IDisposable interface is implemented
       } } `
    | ft }                                          # Format all returned objects as a table
_
4
jimbobmcgee

either using or in Dispose() method可能な場合はusing構文を使用してください。これが理由です。このMSDNの例を使用して、2つの同等のコードブロックを次に示します。これはusing付きです:

using (Font font1 = new Font("Arial", 10.0f)) 
{
    byte charset = font1.GdiCharSet;
}

これはusingなし:

{
    Font font1 = new Font("Arial", 10.0f);
    try
    {
        byte charset = font1.GdiCharSet;
    }
    finally
    {
        if (font1 != null)
            ((IDisposable)font1).Dispose();
    }
}

2番目のブロックの各部分が存在する理由は、中括弧、try-finally、nullチェック、およびIDisposableへのキャストです。誰もがこれを覚えていると期待されるべきではありません。そのため、using構成が存在します。

0
user2023861