我发现在我编写的许多简单的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()覆盖来列出公共属性,还是有一个很好的约定?
答案 0 :(得分:16)
您可以在基类中重写ToString,然后在实例上使用反射来发现派生类的公共属性。但这可能会在代码的其他方面引入性能问题。另外,因为ToString被很多东西使用(String.Format,默认数据绑定等)来覆盖ToString用于调试目的会使你的类在其他场景中不那么有用。
相反,您可能希望使用DebuggerDisplay属性来控制调试器在监视窗口中显示悬停提示和信息的方式等。如果你将它应用于基类,我很确定这是有效的。您还可以创建自定义可视化工具,但更复杂。有关增强调试器显示体验的更多信息,请查看此链接。
答案 1 :(得分: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, “值”: “测试”}
答案 2 :(得分:0)
这不是一个好的设计考虑因素。我建议你提取你需要记录它们的值或者有一个帮助方法(你可以在System.Object上使用扩展方法)。
答案 3 :(得分: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 )
}
[有条件]属性是您问题的关键。
答案 4 :(得分:0)
聆听那些警告您性能和/或设计注意事项的人。当你可以通过使用扩展或装饰来解除你的需求时,你就会紧紧地绑定一个行为以满足非常有限的需求。
答案 5 :(得分: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);
}
}