web-dev-qa-db-fra.com

Vous reconnaissez des objets jetables dans Visual Studio?

Il est suggéré que les objets IDisposable soient supprimés dans l'instruction using ou en appelant la méthode Dispose(). Je trouve qu'il n'est pas intuitif de savoir si un objet est jetable dans Visual Studio.

Ma question est: existe-t-il un moyen de reconnaître les objets IDisposable dans VS?

23
T D Nguyen

Si vous souhaitez mettre en surbrillance les objets jetables différemment dans VS, veuillez consulter ceci post . Personnellement, je préfère Resharper réponse car j'utilise toujours R #.

Si vous voulez juste savoir si votre objet est une instance d'une interface, vous pouvez cliquer avec le bouton droit sur le nom de la variable et Navigate -> Object Browser Ou Go to Declaration Puis cliquer avec le bouton droit sur la classe nom Go to Definition/Peek Definition.

enter image description here

Vous pourriez aimer Peek Definition Car il montre tout ce dont vous avez besoin en ligne:

enter image description here

Vous pouvez toujours vérifier quelles méthodes l'objet a, s'il a la méthode Dispose() alors 99,9% c'est un objet jetable. Je donnerai ce 0,01% pour ceux qui donnent des mauvais noms aux méthodes :).

29
Andrei

Je suis surpris que personne d'autre ne l'ait encore mentionné. Si votre édition de Visual Studio le prend en charge, je vous suggère d'activer Code Analysis pour Build.

Une fois cela fait, choisissez les jeux de règles que vous aimez tant qu'ils garantissent au moins CA20 (Éliminez les objets avant de perdre la portée), CA221 (Les champs jetables doivent être éliminées) et CA2202 (Ne pas éliminer les objets plusieurs fois) sont couvertes. De cette façon, le compilateur devrait vous crier si vous ne traitez pas correctement les objets jetables.

(Bien que notez qu'obtenir que le compilateur ne marque pas une certaine utilisation des objets jetables peut alors devenir le plus grand défi, comme de nombreuses questions StackOverflow peuvent en témoigner)

14

Vous pouvez utiliser l'Explorateur d'objets pour afficher la hiérarchie d'héritage de classe avec les interfaces implémentées

enter image description here

8
Aleksey L.

Par souci d'exhaustivité, si vous ne demandez pas comment le vérifier dans votre code mais que vous voulez simplement savoir où vous pouvez regarder si le type implémente une interface comme IDisposable, vous pouvez toujours regarder - MSDN .

Par exemple FileStream

  • c'est déjà mentionné dans la section des remarques:

Ce type implémente l'interface IDisposable. Lorsque vous avez fini d'utiliser le type, vous devez le supprimer directement ou indirectement. Pour supprimer directement le type, appelez sa méthode Dispose dans un bloc try/catch. Pour en disposer indirectement, utilisez une construction de langage telle que using (en C #) ou Using (en Visual Basic). Pour plus d'informations, consultez la section "Utilisation d'un objet qui implémente IDisposable" dans la rubrique relative à l'interface IDisposable.

  • ou recherchez la méthode Dispose . Là, vous pouvez voir si cette classe ou toute classe parent implémente IDispable. Dans ce cas, il est hérité de Stream qui implémente cette interface qui est mentionnée dans la syntaxe de classe et dans la section des remarques.

    public abstract class Stream : MarshalByRefObject, IDisposable
    

Si vous voulez savoir comment trouver les implémentations d'une interface dans Visual Studio , voici déjà une question qui répond à cela:

Comment trouvez-vous toutes les implémentations d'une interface?

6
Tim Schmelter

Un moyen de voir quelles interfaces une classe implémente, ainsi que tous ses champs, propriétés, méthodes, etc. exposés publiquement, consiste à accéder à cette classe dans le code. Par exemple:

Image image = Image.FromFile(path);

Assurez-vous de cliquer sur la classe, pas sur l'instance et appuyez sur F12. Cela vous amènera à un fichier de métadonnées pour cette classe. Par exemple: le fichier Image.cs A la déclaration de classe ci-dessus:

public abstract class Image : MarshalByRefObject, ISerializable, ICloneable, IDisposable

Vous pouvez ensuite également utiliser F12 pour cliquer sur d'autres classes. Notez que ces classes sont généralement affichées dans la couleur bleu clair dans Visual Studio:

Screenshot showing light blue colours.

Vous pouvez également accéder à ce fichier de métadonnées en cliquant avec le bouton droit sur la classe et en sélectionnant "Aller à la définition" dans la liste déroulante.


Bien que ce ne soit pas idéal, vous pouvez également aller à une instance de la classe et mettre un . À la fin. Cela devrait faire apparaître l'intellisense et vous pourrez voir Dispsose() dans la liste si l'élément implémente l'interface.

Vous pouvez aussi simplement écrire myInstance.Dispose(); ou using (myInstance = new MyClass()) {} et si elle compile la classe implémente l'interface sinon elle ne le fait pas.

5
TheLethalCoder

Comme alternative (idiote?) Au décorticage pour Resharper et ses semblables, Visual Studio a le concept de Outils externes (dans le menu Outils), que vous pourriez (ab) utiliser pour faire quelque chose comme:

  • Titre:Is Disposa&ble
  • Commande:C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe
  • Arguments:-Command "&{$i=[Type]::GetType('System.IDisposable');[AppDomain]::CurrentDomain.GetAssemblies()|%{ $_.GetTypes()}|?{$_.FullName.EndsWith('.$(CurText)')}|%{New-Object PSObject -Property @{'Type'=$_;'IDisposable'=$i.IsAssignableFrom($_)}}|ft}"
  • tiliser la fenêtre de sortie: cochée

Cela lirait la chaîne que vous aviez sélectionnée dans l'éditeur, rechercherait les types .NET avec cette chaîne comme nom et afficherait True/False pour savoir si cette chaîne implémentait IDisposable.

La commande Powershell dans l'outil n'est que l'approche la plus rapide que je pouvais faire pour démontrer la possibilité, mais elle est loin d'être parfaite - elle ne trouve que des types dans assemblages que Powershell charge par défaut. Si vous souhaitez développer l'idée, vous pouvez créer une application .NET en ligne de commande qui a chargé votre projet et analysé tous les assemblages chargés par votre projet.

Si vous avez mis en surbrillance le mot Stream dans votre code, par exemple, et exécuté votre outil externe (ALT+T,ALT+B dans l'exemple), il retournerait:

Tapez IDisposable 
 ---- ----------- 
 System.IO.Stream True

Pour décomposer la commande 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 Utilisez la construction using lorsque vous le pouvez. Voici pourquoi. En utilisant cet exemple MSDN, voici deux blocs de code équivalents. Celui-ci avec using:

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

Celui-ci sans using:

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

Chaque partie du deuxième bloc est là pour une raison: les accolades, le try-finally, la vérification nulle et le transtypage en IDisposable. Personne ne devrait s'en souvenir. C'est pourquoi la construction using existe.

0
user2023861