2010-05-08 15 views
5

? Tengo varias clases que están decoradas con DebuggerDisplayAttribute.¿Existe un método para representar un objeto utilizando DebuggerDisplayAttribute

Quiero ser capaz de agregar declaraciones de seguimiento a las pruebas unitarias que mostrarán instancias de estas clases.

¿Existe un método en .NET Framework que muestre un objeto formateado con DebuggerDisplayAttribute (o recurra a .ToString() si no se define DebuggerDisplayAttribute)?

EDITAR

Para aclarar, yo estaba esperando que podría haber algo integrado en el Marco. Sé que puedo obtener la propiedad Value de DebuggerDisplayAttribute, pero luego necesito formatear mi instancia utilizando la cadena de formato representada por DebuggerDisplayAttribute.Value.

Si ruedo mi propia, me prever un método de extensión a lo largo de las siguientes líneas:

public string FormatDebugDisplay(this object value) 
{ 
    DebugDisplayAttribute attribute = ... get the attribute for value ... 
    if (attribute = null) return value.ToString(); 

    string formatString = attribute.Value; 

    ??? How do I format value using formatString ??? 
    return SomeFormatMethod(formatString, value); 
} 

Respuesta

2

Eso podría ser bueno, pero la cadena de formato de DebuggerDisplayAttribute es evaluada por el depurador, de la misma manera que evalúa las expresiones que escribe en la ventana Inspección o r la ventana Inmediata. Es por eso que puedes poner expresiones arbitrarias dentro de las llaves, como {FirstName + " " + LastName}.

Por lo tanto, para evaluar esto en su código, deberá incrustar el depurador de Visual Studio en su aplicación. Probablemente no va a suceder. (sonrisa)

Probablemente su mejor opción sea tomar toda la lógica de formateo que está actualmente en su cadena de formato DebuggerDisplay, y convertirla en un método en su lugar. Entonces puedes llamar a ese método desde tu código. Su atributo DebuggerDisplay termina haciendo nada más que llamar al método.

[DebuggerDisplay("{Inspect()}")] 
public class MyClass { 
    public string Inspect() { ... } 
} 
+0

Gracias. Escribir mi propio método en la forma en que describes es una especie de derrota para el propósito de lo que estaba tratando de lograr. Me he ido con la anulación de ToString() para las clases en cuestión. – Joe

+0

Si el código de su aplicación no asigna ningún significado a ToString(), entonces sí, eso es más simple. En algunos casos, ToString() ya tiene un significado (p.para mostrar el objeto en un cuadro de lista), y en esos casos, DebuggerDisplay plus un método aún puede ser útil. –

+0

No es necesario que "inserte el depurador de Visual Studio en su aplicación" para escribir un método que proporcione valor. Sospecho que la mayoría de los usos de DebuggerDisplay son valores de propiedad simples, y su implementación sería un método valioso. –

1

El DebuggerDisplayAttribute tiene una propiedad Value que devuelve lo que quiere.

Así que probablemente se podría usar algo como esto:

var attribute = obj.GetType(). 
    GetCustomAttributes(typeof(DebuggerDisplayAttribute), false); 
return (attribute == null) ? obj.ToString() : attribute.Value; 

Incluso se puede poner esto en un método de extensión:

public static string ToDebugString(this object obj) 
{ 
    var attribute = obj.GetType(). 
     GetCustomAttributes(typeof(DebuggerDisplayAttribute), false); 
    return (attribute == null) ? obj.ToString() : attribute.Value; 
} 

la que puede llamar en cada objeto: myObject.ToDebugString()

+1

Sí, sé que puedo hacer mi propia pregunta, la pregunta era si algo ya existe. Su muestra no ayuda; solo mostrará la cadena de formato del atributo en lugar de formatear obj utilizando la cadena de formato. – Joe

0

Este método no implementar exactamente lo DebuggerDisplayAttribute ofrece en el depurador, pero esto es lo que he estado usando en mi código. Cubre aproximadamente el 90% (o más) de los casos que experimentamos en nuestra base de código. Si lo arreglas para cubrir incluso más casos, ¡me encantaría ver tus mejoras!

public static string ToDebuggerString(this object @this) 
    { 
     var display = @this.GetType().GetCustomAttributes(typeof (DebuggerDisplayAttribute),false).FirstOrDefault() as DebuggerDisplayAttribute; 
     if (display == null) 
      return @this.ToString(); 

     var format = display.Value; 
     var builder = new StringBuilder(); 
     for (var index = 0; index < format.Length; index++) 
     { 
      if (format[index] == '{') 
      { 
       var close = format.IndexOf('}', index); 
       if (close > index) 
       { 
        index++; 
        var name = format.Substring(index, close - index); 
        var property = @this.GetType().GetProperty(name); 
        if (property != null) 
        { 
         var value = property.GetValue(@this, null).ToString(); 
         builder.Append(value); 
         index += name.Length; 
        } 
       } 
      } 
      else 
       builder.Append(format[index]); 
     } 
     return builder.ToString(); 
    } 
Cuestiones relacionadas