簡體   English   中英

有沒有辦法在類上自動覆蓋ToString()?

[英]Is there a way to automatically override ToString() on a class?

我發現在我編寫的許多簡單的DTO / POCO類上重寫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()覆蓋來列出公共屬性,或者是否有一個好的約定?

您可以在基類中重寫ToString,然后在實例上使用反射來發現派生類的公共屬性。 但這可能會在代碼的其他方面引入性能問題。 另外,因為ToString被很多東西(String.Format,默認數據綁定等)使用而覆蓋ToString用於調試目的會使你的類在其他場景中不那么有用。

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

增強調試

你可以使用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, “值”: “測試”}

如果你不介意外部依賴,你可以轉向一個框架,幫助打印所有對象屬性,如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);
  }
}

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

這是一種可以以調試器友好的方式完成的方式

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 )

}

[Conditional]屬性是您問題的關鍵。

聆聽那些警告您性能和/或設計注意事項的人。 當你可以通過使用擴展或裝飾來解耦你的需求時,你就緊緊地綁定了一個行為,以滿足非常有限的需求。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM