代码之家  ›  专栏  ›  技术社区  ›  Rob Packwood

有没有办法自动重写类上的ToString()?

  •  10
  • Rob Packwood  · 技术社区  · 16 年前

    我发现在我编写的许多简单的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()重写,或者有一个好的约定可以遵循?

    6 回复  |  直到 16 年前
        1
  •  16
  •   Josh    16 年前

    可以重写基类中的ToString,然后在实例上使用反射来发现派生类的公共属性。但这可能会在代码的其他区域引入性能问题。此外,由于ToString被很多东西(String.Format、默认数据绑定等)使用,因此出于调试目的重写ToString会使类在其他场景中不太有用。

    Enhancing Debugging

        2
  •  1
  •   Carlo V. Dango    12 年前

    如果您不介意外部依赖,可以使用框架来帮助打印所有对象属性,如 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);
      }
    }
    
        3
  •  1
  •   Dallas    11 年前

    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”}

        4
  •  0
  •   Ivan G.    16 年前

    这不是一个好的设计考虑。我建议您在需要记录值或有助手方法的地方提取值(您可以在System.Object上使用扩展方法)。

        5
  •  0
  •   No Refunds No Returns    16 年前

    这里有一个方法,它可能是在一个调试友好的方式

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

        6
  •  0
  •   Michiel van Oosterhout    14 年前

    听听那些在性能和/或设计方面警告你的人的意见。当您可以通过使用扩展或装饰器来分离您的需求时,您正在紧密地绑定一个行为以满足非常有限的需求。