2010-02-26 58 views
10

我發現在我編寫的許多簡單的DTO/POCO類上覆蓋ToString()時,可以在調試器中懸停實例時顯示一些很好的信息。有沒有辦法自動覆蓋類的ToString()?

下面是一個例子:

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

是否有.NET的方式來自動擁有一個ToString()重寫,列出了公共屬性還是有遵循好習慣?

回答

16

您可以在基類中重寫ToString,然後在實例上使用反射來發現派生類的公共屬性。但是這可能會在你的代碼的其他領域引入性能問題。此外,由於ToString被很多事情(String.Format,默認數據綁定等)使用,所以爲了調試目的而重寫ToString將使您的類在其他場景中的用處變得更小。

相反,您可能希望使用DebuggerDisplay屬性來控制調試器在監視窗口等中顯示懸停提示和信息的方式。如果你將它應用到基類,我很肯定這是有效的。您也可以創建自定義的可視化工具,但這更涉及。查看此鏈接以獲取有關增強調試器顯示體驗的更多信息。

Enhancing Debugging

+1

謝謝!我所要做的就是將這個屬性添加到我最初發布的類中,並且它表現得如我所願: [DebuggerDisplay(「Id:{Id} Value:{Value}」)] – 2010-02-26 18:07:45

0

這不是一個好的設計考慮因素。我建議你在需要記錄它們或者有一個幫助方法的地方提取值(你可以在System.Object上使用擴展方法)。

0

這裏的一個方式,它可能會在調試器友好的方式

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) 

} 

的[條件]屬性來完成的關鍵是你的問題。

+2

ConditionalAttribute實際上更適合於你正在向另一個調用者公開一個你不知道的構建配置的方法。在這種情況下,您可以使用#if DEBUG實現相同的結果,而不會造成呼叫站點模糊性。但這是一個非常有用且鮮爲人知的屬性! – Josh 2010-02-26 17:49:54

0

傾聽那些警告你關於性能和/或設計考慮的人。當你使用擴展或裝飾器解耦你的需求時,你緊緊地綁定了一個適合相當有限需求的行爲。

0

如果你不介意的外部的依賴,你可以把一個框架,打印所有對象的屬性一樣StatePrinter

使用示例

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

你可以使用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(); 
     } 
    } 
} 

哪個給出了這樣的輸出:

{「Id」:1,「Value」:「Test」}

相關問題