Depurar sin complicarnos la vida utilizando Debugging Attributes

29 05 2008

Cuando depuramos con Visual Studio es un verdadero fastidio el hecho de tener que entrar a todos los métodos o propiedades que se encuentran dentro de una llamada, por ejemplo:

void MiMétodo(DameUnString())
{
   //algo acá que si quiero depurar
}
String DameUnString()
{
   //¡No quiero depurar esto!
   return "Este es tu String!";
}

DebuggerStepThrough y DebuggerHidden

Cuando se trabaja en cualquier sistema medianamente complejo es muy molesto depurar código como el anterior ya que no hay manera en VS de indicar que queremos ir directamente al cuerpo del método que estamos por depurar, sin entrar a cada parámetro.

Lo mismo ocurre cuando presionamos por error F11 en vez de F10 y entramos a un interminable método que nos obliga a poner un break al final (y luego a quitarlo para no parar nuevamente)

Una solución parcial pero util son los atributos DebuggerStepThrough y DebuggerHidden.

Poniendo DebuggerHidden a un método logramos que Visual Studio no pase nunca por el método:

[System.Diagnostics.DebuggerHidden]
String DameUnString(){...}

hará que nunca depuremos el método DameUnString.

En cambio con el más util DebuggerStepThrough, el entorno se detiene en el método si colocamos un break, pero no de otra manera.

Realmente sería más util una tecla para “Avanzar StepThrough”, incluso por ahí he visto una solicitada para su inclusión en VS…pero esta es la solución parcial que tenemos disponible.

DebuggerBrowsable y DebuggerDisplay

Por defecto VS nos permite ver los miembros privados de las clases y estructuras que escribimos al momento de depurarlas. Si bien esto puede ser util, cuando la clase es un contenedor de datos, no es práctico disponer de esta información que está expuesta nuevamente en las propiedades públicas. Ni hablar si nuestra clase va a ser expuesta a terceros.

Por ejemplo si depuramos una clase “Persona” con tres propiedades vemos en la ventana de Watch una molesta duplicación de datos:

El atributo DebuggerBrowsable nos permite especificar que no se deben mostrar en el depurador los métodos, miembros o propiedades decorados con el mismo.

DebuggerDisplay, a su vez, nos permite especificar el texto a mostrar en la columna value de las ventanas de depuración. En la cadena que nos pide podemos especificar entre llaves “{}” código ejecutable, pero la mejor manera de entender esto es ver un ejemplo. Si la clase de la imagen anterior estuviera declarada de la siguiente manera:

[DebuggerDisplay("{this.GetType().ToString(),nq} ({_nombre,nq} {_apellido,nq}, {_edad} años)")]
public struct Persona {...}

(nq significa “No Quotes”, para quitar las comillas de las cadenas)

y los miembros privados estuvieran decorados así:

[DebuggerBrowsable(DebuggerBrowsableState.Never)]
private Int32 _edad;

Entonces lo que veríamos en la ventana de Watch sería:

Mucho más claro si tenemos en cuenta que el tipo persona lo escribiremos una sola vez pero lo depurarán por miles de años.

Hay otros atributos de debugging que permiten desde wrappear en otra clase lo que se va a mostrar al depurar, hasta implementar un viewer customizado para un tipo, como el que Visual Studio trae para el DataSet.

Nota: No olvidar que estos atributos pertenecen al namespace System.Diagnostics, por lo que hay que agregar el correspondiente using/Imports.

Anuncios