DebuggerDisplayAttribute
Un truco sencillo que acabo de descubrir. Observe la imagen:
Depurando, si paso el ratón sobre el parámetro map, que pertenece a un tipo TypeMap que he definido, se muestra el número de elementos almacenados por este contenedor. ¿Cómo se logra? Parece sencillo: basta con redefinir el método ToString en la clase TypeMap. Y es verdad que eso funciona... pero hay una alternativa que muchas veces es mejor. Se trata de decorar la clase con el atributo DebuggerDisplay:
[DebuggerDisplay("Items = {items.Count}")]
internal sealed class TypeMap
Observe que el parámetro pasado al atributo es una especie de cadena de formato que permite incluir expresiones entre llaves. En este caso, mostramos el valor de la propiedad Count de un campo de TypeMap llamado items.
¿Porque me alegra tanto tener una alternativa a la redefinición de ToString? Porque así puedo separar con más claridad la lógica de la aplicación del código auxiliar que sólo necesito durante la depuración del proyecto. En el compilador de Freya, por ejemplo, los símbolos de métodos redefinen ToString para facilitar la búsqueda en la tabla de símbolos, pero otras clases lo hacían sólo por conveniencia, para mostrar información durante la depuración. Con el listado delante, me costaba normalmente decidir si determinada reescritura de ToString era necesaria o prescindible.
11 Comments:
Está bien cuando lo que quieres mostrar es lo suficientemente sencillo como para describirlo con una expresión.
Cuando hay que poner algo más complejo lo que yo hago es sobreescribir ToString() con una directiva de compilación condicional #if (DEBUG)
:) Me too... La verdad es que complicar mucho la expresión del atributo no es bueno. Por cierto, a los fans de los ORM, el atributo les viene que ni hecho a la medida: dado el carácter de las clases de entidades en un ORM típico (mero depósito de información), les bastará poner un par de "columnas" para facilitarles la depuración.
¿Sabes si ese atributo se elimina de la versión "Release"?
Si no me voy a quedar con ToString() para todo.
No, no se elimina: para eso tendría que descender de ConditionalAttribute.
¡Pues que chapuza! ¿Que sentido tiene un attributo llamado DebuggerDisplay en una versión final?
Imagina que se trata de una biblioteca de componentes. Lo ideal sería tener dos versiones binarias, como mínimo: una para tirar millas y la otra para depurar... pero hoy por hoy, no existe tal cosa. La decisión es un compromiso, supongo, pero en todo caso, no hace mucho daño, pues el atributo no ocupa espacio en la instancia.
Pues a mi me parece que cae de cajón que si vas a distribuir una biblioteca de componentes en versión binaria tienes que distribuir dos versiones, la final y la de depuración. La de depuración tendría que tener muchas más comprobaciones.
Como solución cutre se puede usar una directiva de compilación para el atributo :-)
:) He visto este comentario ahora:
Una bitácora es un armario, un log es un cuaderno como por ejemplo un diario. Un cuaderno de bitácora es un cuaderno que se guarda en un armario.
Sí, y un "log" es un trozo de madera. Deriva semántica, lo llaman.
Por cierto, y ya en plan sabihondo, ¿sabías de dónde viene el uso de "nick" como "apodo"? De "an eek name", del antiguo inglés, donde el "eek" significaba "otro". En el proceso de rebracketing la N se pasó de palabra. Es lo contrario que le pasó a la N de Naranja en inglés: la palabra original es narangi, en no recuerdo qué idioma de la India. En inglés (o quizás en francés), "a norange" terminó convirtiéndose en "an orange".
Pues a mi me parece que cae de cajón que si vas a distribuir una biblioteca de componentes en versión binaria tienes que distribuir dos versiones, la final y la de depuración
... y que la de depuración traiga activos los invariantes de clase y las postcondiciones: las precondiciones deben verificarse, según la ortodoxia, en el lado cliente. Se supone que las precondiciones verifican el buen uso de los contratos por parte del consumidor.
Hace ya un tiempo, Hejlsberg dijo que estaban dándole vueltas a dar algún soporte para Design by Contract en .NET (supongo que al nivel de la CLR). Pero no lo dijo con mucho convencimiento...
Sí, y un "log" es un trozo de madera. Deriva semántica, lo llaman.
Lo que quería decir es que no hay que traducir log como bitácora, sino como diario o cuaderno. No se a quien se le ocurrió eso.
¿sabías de dónde viene el uso de "nick" como "apodo"? De "an eek name", del antiguo inglés, donde el "eek" significaba "otro". En el proceso de rebracketing la N se pasó de palabra.
Pues no tenía ni idea. Y yo que pensaba que vendría de: nombre corto, con "nick" como corte o como forma corta de Nicholas O:-)
Nick Rivers dijo que a su padre se le ocurrió su nombre mientras se afeitaba :-)
Pero resulta que es todo lo contrario, que viene de "nombre adicional", relacionado con "eacian" que era incrementar. Las cosas que hace la imaginación :-)
Pero en la Wikipedia pone que es "an eke name", no "an eek name"
Pero en la Wikipedia pone que es "an eke name", no "an eek name"
Muy cierto. Demostración de que citaba de memoria.
con "nick" como corte o como forma corta de Nicholas
Nick es también "el viejo Nick", "Old Nicholas", o como dice Mick, "that man of wealth and taste". Y tiene que ver con el nombre del níquel: el kupfernickel o "cobre del diablo" (y el cobalto debe su nombre a los "kobolds").
Publicar un comentario
<< Home