2010-02-26 21 views
10

Trovo utile sovrascrivere ToString() su molte delle classi DTO/POCO semplici che scrivo per mostrare alcune buone informazioni quando si passa sopra le istanze all'interno del debugger.C'è un modo per sovrascrivere automaticamente ToString() su una classe?

Ecco un esempio:

public class IdValue<T> 
    { 
    public IdValue(int id, T value) 
    { 
     Id = id; 
     Value = value; 
    } 

    public int Id { get; private set; } 
    public T Value { get; private set; } 

    public override string ToString() 
    { 
     return string.Format("Id: {0} Value: {1}", Id, Value); 
    } 
    } 

C'è un modo in .NET per avere automaticamente una sostituzione di ToString(), che elenca le proprietà pubbliche o c'è una buona convenzione da seguire?

risposta

16

È possibile eseguire l'override di ToString in una classe base, quindi utilizzare la riflessione sull'istanza per scoprire le proprietà pubbliche della classe derivata. Ma questo probabilmente introdurrà problemi di prestazioni in altre aree del tuo codice. Inoltre, poiché ToString viene utilizzato da molte cose (String.Format, associazione dati predefinita, ecc.), La sostituzione di ToString per scopi di debug renderà le tue classi meno utili in altri scenari.

Invece, potresti voler usare l'attributo DebuggerDisplay per controllare come il debugger mostra suggerimenti e informazioni al passaggio del mouse nella finestra di controllo e così via. Sono abbastanza sicuro che questo funziona se lo si applica a una classe base. Puoi anche creare visualizzatori personalizzati ma questo è più coinvolto. Dai un'occhiata a questo link per maggiori informazioni su come migliorare l'esperienza di visualizzazione del debugger.

Enhancing Debugging

+1

Grazie! Tutto quello che dovevo fare era aggiungere questo attributo alla classe che avevo postato originariamente e si comportava come volevo: [DebuggerDisplay ("Id: {Id} Value: {Value}")] –

0

Questa non è una buona considerazione di progettazione. Consiglierei di estrarre i valori in cui è necessario registrarli o disporre di un metodo di supporto (è possibile utilizzare i metodi di estensione su System.Object).

0

qui Un modo che potrebbe essere fatto in un debugger modo amichevole

public override string ToString() 
{ 
    stringBuilder sb = ... your usual string output 
    AppendDebug(sb); 
    return sb.Tostring(); 
} 


[Conditional("DEBUG")] 
private void AppendDebug(stringBuilder sb) 
{ 
    sb.Append(... debug - specific info) 

} 

Il [condizionale] attributo è la chiave per la tua domanda.

+2

ConditionalAttribute è davvero più adatto a quando stai esponendo un metodo a un altro chiamante la cui configurazione di build non lo sai in anticipo. In questo caso è possibile ottenere lo stesso risultato senza l'ambiguità del sito di chiamata usando #if DEBUG. Ma è un attributo molto utile e poco conosciuto! – Josh

0

Ascolta le persone che ti avvisano delle prestazioni e/o considerazioni di progettazione. Stai vincolando strettamente un comportamento per soddisfare un bisogno piuttosto limitato, quando potresti disaccoppiare le tue esigenze usando un'estensione o un decoratore.

0

Se non ti dispiace una dipendenza esterna, si potrebbe trasformare in un quadro aiutando con la stampa di tutte le proprietà degli oggetti come StatePrinter

Un esempio d'uso

class AClassWithToString 
{ 
    string B = "hello"; 
    int[] C = {5,4,3,2,1}; 

    // Nice stuff ahead! 
    static readonly StatePrinter printer = new StatePrinter(); 
    public override string ToString() 
    { 
    return printer.PrintObject(this); 
    } 
} 
1

Si potrebbe utilizzare JSON:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
using System.Web.Script.Serialization; 

namespace ConsoleApplication1 
{ 
    public class IdValue<T> 
    { 
     public IdValue(int id, T value) 
     { 
      Id = id; 
      Value = value; 
     } 

     public int Id { get; private set; } 
     public T Value { get; private set; } 

     public override string ToString() 
     { 
      return new JavaScriptSerializer().Serialize(this); 
     } 
    } 

    class Program 
    { 
     static void Main(string[] args) 
     { 
      var idValue = new IdValue<string>(1, "Test"); 
      Console.WriteLine(idValue); 
      Console.ReadKey(); 
     } 
    } 
} 

che dà questo output:

{"Id": 1, "Valore": "Test"}

Problemi correlati