c# .net visual-studio intellisense idisposable

c# - ¿Reconoce objetos desechables en Visual Studio?



.net visual-studio (9)

Algo limpio que se puede hacer en C # 7.

class Foo : IDisposable { string _bar = "init"; void Fooy() { _bar = "fooy"; } public void Dispose() { _bar = null; } static void Main() { var v = new Foo(); Console.WriteLine(v._bar); if(v is IDisposable id) using(id) v.Fooy(); else v.Fooy(); Console.WriteLine(v._bar ?? "null");; } }

Fooy podría ser alguna función virtual o abstracta . Algunas clases base pueden implementar IDisposable mientras que otras no. Intente ejecutar el código anterior. La consola imprimirá texto diferente dependiendo de si IDisposable ha sido implementado o no IDisposable

Se sugiere que los objetos IDisposable deben eliminarse ya sea using declaración o llamando al método Dispose() . Me parece que no es intuitivo averiguar si un objeto es desechable en Visual Studio.

Mi pregunta es: ¿hay alguna manera de reconocer objetos IDisposable en VS?


Como una adición a la excelente respuesta de Andrei, si está usando C # 7, puede usar esta nueva sintaxis:

if(obj is IDisposable disposableObject) { disposableObject.Dispose(); }


Como una alternativa (¿tonta?) A eliminar a Resharper y su tipo, Visual Studio tiene el concepto de herramientas externas (en el menú Herramientas), que podría (ab) usar para hacer algo como:

  • Título: Is Disposa&ble
  • Comando: C:/Windows/System32/WindowsPowerShell/v1.0/powershell.exe
  • Argumentos: -Command "&{$i=[Type]::GetType(''System.IDisposable'');[AppDomain]::CurrentDomain.GetAssemblies()|%{ $_.GetTypes()}|?{$_.FullName.EndsWith(''.$(CurText)'')}|%{New-Object PSObject -Property @{''Type''=$_;''IDisposable''=$i.IsAssignableFrom($_)}}|ft}"
  • Utilizar ventana de salida: marcada

Esto leería cualquier cadena que haya seleccionado en el editor, busque tipos de .NET con esa cadena como nombre y muestre un Verdadero / Falso en cuanto a si esa cadena se implementó como IDisposible.

El comando Powershell en la herramienta es solo el método más rápido que podría hacer para demostrar la posibilidad, pero está lejos de ser perfecto: solo encuentra los tipos en ensamblajes que Powershell carga de forma predeterminada. Si desea expandir la idea, puede crear una aplicación .NET de línea de comandos que cargue su proyecto y escanee todos los ensamblajes que su proyecto cargó.

Si resaltara la palabra Stream en su código, por ejemplo, y ejecutó su herramienta externa ( ALT + T , ALT + B en el ejemplo), devolvería:

Type IDisposable ---- ----------- System.IO.Stream True

Para descomponer el comando 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


En aras de la integridad, si no pregunta cómo verificarlo en su código, pero solo quiere saber dónde puede buscar si el tipo implementa una interfaz como IDisposable , siempre puede consultar MSDN .

Por ejemplo FileStream

  • Ya se menciona en la sección de comentarios:

Este tipo implementa la interfaz IDisposable . Cuando haya terminado de usar el tipo, debe desecharlo directa o indirectamente. Para eliminar el tipo directamente, llame a su método Dispose en un bloque try / catch. Para eliminarlo indirectamente, use una construcción de lenguaje como, por ejemplo, usar (en C #) o Usar (en Visual Basic). Para obtener más información, consulte la sección "Uso de un objeto que implementa IDisposable" en el tema de la interfaz IDisposable.

  • o busque el método Dispose . Allí puede ver si esta clase o cualquier clase padre implementa IDispable . En este caso, se hereda de Stream que implementa esa interfaz que se menciona en la sintaxis de la clase y en la sección de comentarios.

    public abstract class Stream : MarshalByRefObject, IDisposable

Si desea saber cómo encontrar implementaciones de una interfaz en Visual Studio , aquí hay una pregunta que responde que:

¿Cómo encuentras todas las implementaciones de una interfaz?


Me sorprende que nadie más haya mencionado esto todavía. Si su edición de Visual Studio lo admite, sugeriría activar el análisis de código para compilar.

Una vez hecho esto, elija los conjuntos de reglas que desee, siempre y cuando garanticen que, al menos, CA2000 ( CA2000 objetos antes de perder el alcance), CA2213 (los campos desechables deben eliminarse) y CA2202 (no deseche los objetos varias veces) las reglas son cubierto. De esa manera, el compilador debería gritarte si no estás tratando con objetos desechables correctamente.

(Aunque tenga en cuenta que hacer que el compilador no marque algo de uso de objetos desechables puede convertirse en un desafío mayor, como lo pueden constatar muchas preguntas de )


Puede utilizar el Examinador de objetos para ver la jerarquía de herencia de clases con las interfaces implementadas


Si desea resaltar los objetos desechables de manera diferente en VS, consulte esta post . Personalmente prefiero la answer Resharper ya que siempre uso R #.

Si solo quiere saber si su objeto es una instancia de alguna interfaz, puede hacer clic con el botón derecho en el nombre de la variable y Navigate -> Object Browser o Go to Declaration y luego hacer clic con el botón derecho en el nombre de la clase Go to Definition / Peek Definition .

Es posible que le guste Peek Definition ya que muestra todo lo que necesita en línea:

Siempre puede verificar qué métodos tiene el objeto, si tiene el método Dispose() , entonces el 99.9% es un objeto desechable. Daré este 0.01% para aquellos que dan malos nombres a los métodos :).


Una forma de ver qué interfaces implementa una clase, junto con todos los campos, propiedades, métodos, etc. expuestos públicamente, es ir a esa clase en el código. Por ejemplo:

Image image = Image.FromFile(path);

Asegúrese de hacer clic en la clase, no en la instancia y presione F12. Esto te llevará a un archivo de metadatos para esa clase. Por ejemplo: el archivo Image.cs tiene la siguiente declaración de clase anterior:

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

También puede usar F12 para hacer clic a través de otras clases. Tenga en cuenta que estas clases generalmente se muestran en color azul claro en Visual Studio:

También puede acceder a este archivo de metadatos haciendo clic derecho en la clase y seleccionando "Ir a definición" en la lista desplegable.

Aunque no es lo ideal, también puede ir a una instancia de la clase y poner un . al final. Esto debería Dispsose() podrá ver Dispsose() en la lista si el elemento implementa la interfaz.

También myInstance.Dispose(); escribir myInstance.Dispose(); o using (myInstance = new MyClass()) {} y si compila la clase implementa la interfaz, de lo contrario no lo hará.


either using or in Dispose() method Use la construcción using cuando pueda. Este es el por qué. Usando este ejemplo de MSDN, aquí hay dos bloques de código equivalentes. Este con el using :

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

Este sin using :

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

Cada parte del segundo bloque está ahí por una razón: las llaves, la prueba-finalmente, la comprobación de nulos y la conversión a IDisposable. No se debe esperar que nadie recuerde esto. Es por eso que existe la construcción que using .