2010-05-08 15 views
5

Ich habe eine Reihe von Klassen, die mit DebuggerDisplayAttribute geschmückt sind.Gibt es eine Methode zum Rendern eines Objekts mit DebuggerDisplayAttribute

Ich möchte Trace-Anweisungen zu Unit Tests hinzufügen, die Instanzen dieser Klassen angezeigt werden.

Gibt es in .NET Framework eine Methode, die ein Objekt anzeigt, das mit DebuggerDisplayAttribute formatiert wurde (oder auf die Verwendung von .ToString() zurückgreift, wenn kein DebuggerDisplayAttribute definiert ist)?

EDIT

Um zu klären, ich war es etwas in das Framework integriert sein könnte hoffen. Ich weiß, dass ich die Value-Eigenschaft von DebuggerDisplayAttribute abrufen kann, aber ich muss dann meine Instanz formatieren, indem ich die Formatzeichenfolge verwendet, die von DebuggerDisplayAttribute.Value dargestellt wird.

Wenn ich meine eigene Rolle, würde ich eine Verlängerung Methode entlang der folgenden Zeilen ins Auge fassen:

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); 
} 

Antwort

2

Das mag schön sein - aber der Formatstring des DebuggerDisplayAttribute wird vom Debugger ausgewertet, genauso wie er Ausdrücke auswertet, die Sie in die Beobachtungsfenster eingeben. O r das Direktfenster. Aus diesem Grund können Sie beliebige Ausdrücke in die geschweiften Klammern einfügen, z. B. {FirstName + " " + LastName}.

Daher, um diese in Ihrem Code zu bewerten, müssten Sie den Visual Studio-Debugger in Ihre App einbetten. Wahrscheinlich wird es nicht passieren. (grinsen)

Ihre beste Wette ist wahrscheinlich, um alle Formatierungslogik, die derzeit in Ihrem DebuggerDisplay Format Zeichenfolge ist, und machen Sie es stattdessen eine Methode. Dann können Sie diese Methode aus Ihrem Code heraus aufrufen. Ihr DebuggerDisplay-Attribut beendet nichts anderes als die Methode aufzurufen.

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

Danke. Meine eigene Methode so zu schreiben, wie Sie es beschreiben, vereitelt den Zweck dessen, was ich erreichen wollte. Ich habe ToString() für die fraglichen Klassen überschrieben. – Joe

+0

Wenn Ihr Anwendungscode ToString() keine Bedeutung zuweist, dann ist das einfacher. In einigen Fällen hat ToString() bereits eine Bedeutung (z.um das Objekt in einer Listbox anzuzeigen), und in diesen Fällen kann DebuggerDisplay plus eine Methode immer noch nützlich sein. –

+0

Sie müssten den Visual Studio-Debugger nicht in Ihre App einbetten, um eine Methode zu schreiben, die einen Mehrwert bietet. Ich würde vermuten, dass _most_ Verwendung von DebuggerDisplay einfache Eigenschaftswerte sind, und die Implementierung so viel wäre eine wertvolle Methode. –

1

Die DebuggerDisplayAttribute hat eine Value Eigenschaft, die zurückgibt, was Sie wollen.

So könnte man wohl so etwas wie folgt verwenden:

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

Man könnte sogar diese in eine Erweiterung Methode setzen:

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

das Sie es auf jedem Objekt aufrufen kann: myObject.ToDebugString()

+1

Ja, ich weiß, ich kann meine eigene rollen, die Frage war, ob schon etwas existiert. Ihr Beispiel hilft nicht - es wird nur die Formatzeichenfolge des Attributs angezeigt, anstatt obj mit der Formatzeichenfolge zu formatieren. – Joe

0

Diese Methode wird nicht genau das umzusetzen, was DebuggerDisplayAttribute im Debugger bietet, aber das ist, was ich in meinem Code im Einsatz. Es deckt ungefähr 90% (oder mehr) der Fälle ab, die wir in unserer Codebasis erleben. Wenn Sie es reparieren, um noch mehr Fälle zu decken, würde ich gerne Ihre Verbesserungen sehen!

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(); 
    } 
Verwandte Themen