C# 为什么/什么时候覆盖 ToString 是合适的?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10278049/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why / when would it be appropriate to override ToString?
提问by 3D-kreativ
I'm studying C# and I wonder what the point and benefit of overriding ToStringmight be, as shown in the example below.
我正在学习 C#,我想知道重写的意义和好处是什么ToString,如下面的示例所示。
Could this be done in some simpler way, using a common method without the override?
这是否可以以更简单的方式完成,使用没有覆盖的通用方法?
public string GetToStringItemsHeadings
{
get { return string.Format("{0,-20} {1, -20}", "Office Email", "Private Email"); }
}
public override string ToString()
{
string strOut = string.Format("{0,-20} {1, -20}", m_work, m_personal);
return strOut;
}
采纳答案by Konrad Rudolph
Do you need to override
ToString? No.Can you get a string representation of your object in another way? Yes.
你需要覆盖
ToString吗?不。你能用另一种方式得到你的对象的字符串表示吗?是的。
But by using ToStringyou are using a method that is common to all objectsand thus other classes know about this method. For instance, whenever the .NET framework wants to convert an object to a string representation, ToStringis a prime candidate (there are others, if you want to provide more elaborate formatting options).
但是通过使用,ToString您正在使用所有对象通用的方法,因此其他类知道此方法。例如,每当 .NET 框架想要将对象转换为字符串表示时,它ToString就是一个主要候选者(还有其他人,如果您想提供更详细的格式选项)。
Concretely,
具体来说,
Console.WriteLine(yourObject);
would invoke yourObject.ToString().
会调用yourObject.ToString().
回答by Rob Levine
Overriding ToString()allows you to give a useful human-readable string representation of a class.
覆盖ToString()允许您提供一个有用的人类可读的类的字符串表示。
This means that the output can reveal useful information about your class. For example, if you had a Person class you might choose to have the ToString()output the person's id, their firstname, their lastname etc. This is extremely useful when debugging or logging.
这意味着输出可以显示有关您的类的有用信息。例如,如果您有一个 Person 类,您可以选择ToString()输出人的 id、他们的名字、他们的姓氏等。这在调试或记录时非常有用。
With regard to your example - it is difficult to tell if your override is useful without knowing what this class is - but the implementation itself is ok.
关于您的示例 - 在不知道此类是什么的情况下很难判断您的覆盖是否有用 - 但实现本身是可以的。
回答by Jodrell
If you don't override ToStringthen you get your base classes implementation which, for Objectis just the short type name of the class.
如果您不覆盖,ToString那么您将获得基类实现,因为Object它只是类的短类型名称。
If you want some other, more meaningful or useful implementation of ToStringthen override it.
如果您想要其他一些更有意义或更有用的实现,ToString然后覆盖它。
This can be useful when using a list of your type as the datasource for a ListBoxas the ToStringwill be automatically displayed.
这在使用您的类型列表作为 a 的数据源时很有用,ListBox因为ToString将自动显示。
Another situtation occurs when you want to pass your type to String.Formatwhich invokes ToStringto get a representation of your type.
另一种情况发生在您想要将您的类型传递给String.Format调用ToString以获取您的类型的表示形式时。
回答by Robbie
object.ToString()converts an object to its string representation. If you want to change what is returned when a user calls ToString()on a class you have created then you would need to override ToString()in that class.
object.ToString()将对象转换为其字符串表示形式。如果您想更改用户调用ToString()您创建的类时返回的内容,则需要ToString()在该类中进行覆盖。
回答by Andras Zoltan
It's about good practise as much as anything, really.
真的,这和任何事情一样都是关于良好实践的。
ToString()is used in many places to return a string representation of an object, generally for consumption by a human. Often that same string can be used to rehydrate the object (think of intor DateTimefor example), but that's not always a given (a tree for example, might have a useful string representation which simply displays a Count, but clearly you can't use that to rebuild it).
ToString()在许多地方用于返回对象的字符串表示,通常供人类消费。往往是相同的字符串可以用来补充水分对象(想想int还是DateTime为例),但是这并不总是一个给定的(A例如树,可能有这只是显示计数的有用字符串表示,但显然你不能使用重建它)。
In particular the debugger will use this to display the variable in the watch windows, immediate windows etc, therefore ToStringis actually invaluable for debugging.
特别是调试器将使用它在监视窗口、即时窗口等中显示变量,因此ToString对于调试实际上是无价的。
In general, also, such a type will often have an explicit member that returns a string as well. For example a Lat/Long pair might have ToDecimalDegreeswhich returns "-10, 50"for example, but it might also have ToDegreesMinutesSeconds, since that is another format for a Lat/Long pair. That same type might then also override ToStringwith one of those to provide a 'default' for things like debugging, or even potentially for things like rendering web pages (for example, the @construct in Razor writes the ToString()result of a non-string expression to the output stream).
一般来说,这样的类型通常也会有一个显式成员,该成员也返回一个字符串。例如,纬度/经度对可能具有ToDecimalDegrees返回值"-10, 50",例如,但它也可能有ToDegreesMinutesSeconds,因为这是纬度/经度对的另一种格式。然后,该相同类型也可能会覆盖ToString其中之一,以为调试之类的事情提供“默认”,甚至可能为呈现网页之类的事情提供“默认”(例如,@Razor 中的构造将ToString()非字符串表达式的结果写入输出流)。
回答by David Anderson
I'm just going to give you the answer straight from the Framework Design Guidelinesfrom the .NET Development Series.
我将直接从.NET 开发系列的框架设计指南中给出答案。
AVOIDthrowing exceptions from ToString
避免抛出异常ToString
CONSIDERreturning a unique string associated with the instance.
考虑返回与实例关联的唯一字符串。
CONSIDERhaving the output of ToStringbe a valid input for any parsing methods on this type.
考虑将输出作为ToString该类型的任何解析方法的有效输入。
DOensure that ToStringhas no observable side effects.
请确保ToString没有可观察到的副作用。
DOreport security-sensitive information through an override of ToStringonly after demanding an appropriate permission. If the permission demand fails, return a string excluding security-sensitive information.
DO报告通过的重写安全敏感信息ToString只要求苛刻的适当的权限之后。如果权限请求失败,则返回一个不包括安全敏感信息的字符串。
The Object.ToStringmethod is intended to be used for general display and debugging purposes. The default implementation simply provides the object type name. The default implementation is not very useful, and it is recommended that the method be overridden.
该Object.ToString方法旨在用于一般显示和调试目的。默认实现仅提供对象类型名称。默认实现不是很有用,建议重写该方法。
DOoverride ToStringwhenever an interesting human-readable string can be returned. The default implementation is not very useful, and a custom implementation can almost always provide more value.
DO覆盖ToString时可以返回一个有趣的人类可读的字符串。默认实现不是很有用,自定义实现几乎总能提供更多价值。
DOprefer a friendly name over a unique but not readable ID.
DO喜欢一个友好的名称,在特有的,但不能读取ID。
It is also worth mentioning as Chris Sells also explains in the guidelines that ToStringis often dangerous for user interfaces. Generally my rule of thumb is to expose a property that would be used for binding information to the UI, and leave the ToStringoverride for displaying diagnostic information to the developer. You can also decorate your type with DebuggerDisplayAttributeas well.
值得一提的是,Chris Sells 在指南中也解释了这ToString对于用户界面来说通常是危险的。通常,我的经验法则是公开一个用于将信息绑定到 UI 的属性,并保留ToString用于向开发人员显示诊断信息的覆盖。你也可以用它来装饰你的DebuggerDisplayAttribute字体。
DOtry to keep the string returned from ToStringshort. The debugger uses ToStringto get a textual representation of an object to be shown to the developer. If the string is longer than the debugger can display, the debugging experience is hindered.
一定要尽量保持从ToStringshort返回的字符串。调试器用于ToString获取要显示给开发人员的对象的文本表示。如果字符串长于调试器可以显示的长度,则会妨碍调试体验。
DOstring formatting based on the current thread culture when returning culture-dependent information.
返回文化相关信息时,基于当前线程文化的DO字符串格式。
DOprovide overload ToString(string format), or implement IFormattable, if the string return from ToStringis culture-sensitive or there are various ways to format the string. For example, DateTimeprovides the overload and implements IFormattable.
DO提供过载ToString(string format),或实现IFormattable,如果从字符串返回ToString是文化敏感或有各种方式来格式化字符串。例如,DateTime提供重载和实现IFormattable。
DO NOTreturn an empty string or null from ToString
不要从ToString
I swear by these guidelines, and you should to. I can't tell you how my code has improved just by this one guideline for ToString. The same thing goes for things like IEquatable(Of T)and IComparable(Of T). These things make your code very functional, and you won't regret taking the extra time to implement any of it.
我发誓遵守这些准则,你应该这样做。我无法告诉你我的代码是如何通过ToString. 同样的事情也适用于IEquatable(Of T)和 之类的东西IComparable(Of T)。这些东西使您的代码非常实用,您不会后悔花额外的时间来实现其中的任何一个。
Personally, I've never really used ToStringmuchfor user interfaces, I have always exposed a property or method of some-sort. The majority of the time you should use ToStringfor debugging and developer purposes. Use it to display important diagnostic information.
就个人而言,我从来没有真正使用ToString太多的用户界面,我一直都暴露了一些排序的属性或方法。大多数情况下,您应该ToString用于调试和开发人员目的。用它来显示重要的诊断信息。
回答by Dave Cousineau
When defining structs (effectively user-primitives) I find it's good practice to have matching ToString, and Parseand TryParsemethods, particularly for XML serialization. In this case you will be converting the entire state to a string, so that it can be read from later.
在定义结构(实际上是用户原语)时,我发现使用匹配ToString、和Parse和TryParse方法是一种很好的做法,特别是对于 XML 序列化。在这种情况下,您将整个状态转换为字符串,以便稍后读取。
Classes however are more compound structures that will usually be too complex for using ToStringand Parse. Their ToStringmethods, instead of saving the entire state, can be a simple description that helps you identify their state, like a unique identifier like a name or ID, or maybe a quantity for a list.
然而,类是更多的复合结构,通常对于使用ToStringand来说太复杂了Parse。他们的ToString方法,而不是保存整个状态,可以是一个简单的描述,帮助您识别他们的状态,如名称或 ID 等唯一标识符,或者列表的数量。
Also, as Robbie said, overriding ToStringallows you to call ToStringon a reference as basic as type object.
此外,正如 Robbie 所说,覆盖ToString允许您调用ToString与 type 一样基本的引用object。
回答by philologon
In some cases it makes it easier to read values of custom classes in the debugger watch window. If I know exactly what I want to see in the watch window, when I override ToString with that information, then I see it.
在某些情况下,它可以更轻松地在调试器监视窗口中读取自定义类的值。如果我确切地知道我想在监视窗口中看到什么,那么当我用该信息覆盖 ToString 时,我就会看到它。
回答by Daniel James Bryars
One benefit of overriding ToString() is Resharper's tooling support: Alt + Ins -> "Formatting members" and it writes the ToString() for you.
覆盖 ToString() 的好处之一是 Resharper 的工具支持:Alt + Ins ->“格式化成员”,它会为您编写 ToString()。
回答by NickF
You can use that when you have an object with not intuitive meaning of string representation, like person. So if you need for example to print this person you can use this override for preparing it's format.
当您的对象没有字符串表示的直观含义时,您可以使用它,例如人。因此,如果您需要例如打印此人,您可以使用此覆盖来准备其格式。

