6

我刚刚遇到了一些覆盖ToString()并返回一些关键信息(不仅仅是调试信息)的代码。这种类型的用户调用ToString()并解析关键数据。

从多年来阅读的各种点点滴滴来看,我的观点是,它ToString()有一个相当弱的contract,即覆盖它(如果你愿意的话)以显示一些有意义的东西。

看到我说在那里展示了吗?我遇到的代码依赖于这种类型的实例的文本表示非常具体。添加任何超出预期的内容会导致各种问题。

所以,我的问题是,如果对象的文本表示很关键,应该ToString()使用还是应该使用更明确的方法/属性,例如AsText

4

7 回答 7

6

这似乎是一个非常糟糕的计划。如果该类型的用户需要数据,那么该类型应该公开返回该数据的方法。为什么人们在可以访问对象时解析对象的字符串表示形式?

当然有序列化场景,但这些场景定义明确,很少用于.ToString()完成工作。

如果需要用于非输出目的的字符串的文本表示,那么我更喜欢一个单独的方法(可能会或可能不会利用ToString()它来完成它的工作。)这对消费者和实现者都有帮助;如果一个新的编码员想要添加一些调试转储信息ToString()并破坏类的消费者,那将是非常不幸的。

更新:正如 MattDavey 指出的那样,如果您实施IFormattable,那么这是一个很好的折衷方案:您的消费者调用ToString(),但要考虑特定的格式,以及这意味着什么的可靠合同。与您的同事所做的仍然不同,但可能更适合他们的选择。

于 2011-08-10T15:15:08.660 回答
4

我个人同意你的担忧。微软的文档指出该ToString()方法

[...] 将对象转换为其字符串表示形式,以便它适合显示。

Oracle 的Java文档Object.toString()更强大:

结果应该是一个简洁但信息丰富的表示,易于人们阅读。

我认为这些是强烈的迹象,ToString()应该传达对人类方便的信息。返回由应用程序的其他部分操作的数据的方法应该有一个更具信息性的名称。在我看来,甚至AsText()太笼统了。

于 2011-08-10T15:28:25.703 回答
1

我不认为有一个明确的答案。

我会支持使用 .NET 的情况ToString(),因为在 .NET 中创建 API 时,使用 .NET 中的通用命名约定而不是使用不太熟悉的名称(例如 .NET)会受到赞赏AsText()。例如,类遵循此约定StringBuilder,因为它ToString()返回关键信息。

于 2011-08-10T15:17:11.097 回答
1

好问题。

更明确地说,我会为不同的格式创建不同的方法。

例如:toJson() -> 对象的 JSON 表示 toXML() -> 对象的 XML 表示。...ETC

注意:可能有一个库可以为您执行此操作.. 在 java 中有。不知道在c#中

正如您所说,随着时间的推移,解析 toString() 可能会导致问题,因为新开发人员可能不知道 toString() 具有特定格式。

于 2011-08-10T15:19:17.627 回答
0

在我看来ToString()毕竟是一种我们可以以任何理想方式使用它的方法,例如5.ToString()将 int 转换为字符串并返回它,无论它是否用于显示,相反,在许多情况下我们依赖在返回的信息int.ToString()上做进一步的操作。

于 2011-08-10T15:15:57.603 回答
0

没问题,你的问题没有明确的答案。在我看来,像ToStringAsText应该只用于提供对象的内部状态的方法,例如记录它。在面向对象的语言中,功能方面应该通过使用定义良好的接口来派生,GetOrderId例如GetUserName.

于 2011-08-10T15:17:32.657 回答
0

不,我不会那样做。例如,如果我有一个 person 对象,ToString()可能会返回this.firstname + " " + this.lastname. 它正在使用它进行自动显示,例如将项目添加到列表框中。添加对象后,会显示人名。我认为我不会将关键或敏感信息放在覆盖范围内。

于 2011-08-10T15:18:23.820 回答