C# 有没有一种方法可以自动重写类上的ToString()?

C# 有没有一种方法可以自动重写类上的ToString()?,c#,.net,C#,.net,我发现在我编写的许多简单DTO/POCO类上重写ToString()非常有用,以便在将鼠标悬停在调试器内的实例上时显示一些良好的信息 以下是一个例子: public class IdValue< T > { public IdValue( int id, T value ) { Id = id; Value = value; } public int Id { get; private set; } publi

我发现在我编写的许多简单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 );
    }
  }
公共类IdValue
{
公共id值(int id,T值)
{
Id=Id;
价值=价值;
}
public int Id{get;private set;}
公共T值{get;私有集;}
公共重写字符串ToString()
{
返回string.Format(“Id:{0}值:{1}”,Id,Value);
}
}

在.NET中是否有一种方法可以自动使用列出公共属性的ToString()重写,或者有一个好的约定可以遵循?

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

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

相反,您可能希望使用DebuggerDisplay属性来控制调试器如何在监视窗口中显示悬停提示和信息等。如果你把它应用到一个基类上,我很确定这是可行的。您还可以创建自定义可视化工具,但这更复杂。有关增强调试器显示体验的更多信息,请查看此链接


这里有一种方法,可以用调试程序友好的方式完成

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]属性是您问题的关键。

请倾听那些就性能和/或设计考虑事项向您发出警告的人的意见。当您可以通过使用扩展或装饰器来解耦您的需求时,您正在紧密地绑定一个行为以满足非常有限的需求。

如果您不介意外部依赖,您可以求助于一个框架来帮助打印您的所有对象属性,如

用法示例

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);
  }
}
您可以使用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();
        }
    }
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
使用System.Threading.Tasks;
使用System.Web.Script.Serialization;
命名空间控制台应用程序1
{
公共类IdValue
{
公共id值(int id,T值)
{
Id=Id;
价值=价值;
}
public int Id{get;private set;}
公共T值{get;私有集;}
公共重写字符串ToString()
{
返回新的JavaScriptSerializer();
}
}
班级计划
{
静态void Main(字符串[]参数)
{
var idValue=新的idValue(1,“测试”);
控制台写入线(idValue);
Console.ReadKey();
}
}
}
这将产生以下输出:


{“Id”:1,“Value”:“Test”}

ConditionalAttribute实际上更适合于将方法公开给另一个调用方,而您事先不知道该调用方的构建配置。在这种情况下,您可以使用#if DEBUG获得相同的结果,而不会产生调用站点歧义。但这是一个非常有用且鲜为人知的属性!谢谢我所要做的就是将这个属性添加到我最初发布的类中,它的行为符合我的要求:[DebuggerDisplay(“Id:{Id}Value:{Value}”)]