为什么没有与object.ToString()相反?

时间:2017-02-22 15:05:44

标签: c# .net parsing tostring

似乎是一个很好的设计决策,System.Object类,因此.NET中的所有类都提供了一个ToString()方法,毫不奇怪,它返回了对象的字符串表示。此外,在C#中,此方法是针对本机类型实现的,以便它们与类型系统很好地集成。

当需要用户交互时,这通常会派上用场。例如,对象可以直接保存在类似于列表的GUI小部件中,并且可以自动地"显示为文本。

语言设计中没有提供类似的通用object.FromString(string)方法的理由是什么?

其他问题及其答案讨论了可能存在的异议,但我发现它们并不令人信服。

  • 解析可能会失败,而且始终可以转换为字符串。

    • 嗯,这不会使Parse()方法不存在,是吗?如果异常处理被认为是一种不合需要的设计,那么仍然可以定义一个TryParse()方法,其System.Object的标准实现只返回false,但是对于有意义的具体类型,它会被覆盖(例如,无论如何,今天存在方法。

    • 或者,至少有一个IParseable接口可以声明ParseMe()TryParse()方法,与ICloneable一致。

  • Tim Schmelter的评论"滚动自己":当然有效。但我不能编写本机类型的通用代码,或者说,IPAddress如果我必须解析值;相反,我不得不求助于类型内省或编写实现自定义接口的包装器,这种接口要么是维护不友好,要么是单调乏味且容易出错。

  • Damien的评论:接口只能声明非静态函数,原因是Eric Lippert讨论here。这是一个非常有效的反对意见。无法在接口中指定静态TryParse()方法。虚拟ParseMe(string)方法虽然需要一个虚拟对象,但最好是一个kludge,最坏的情况下是不可能的(使用RAII)。我几乎怀疑这是这种界面不存在的主要原因。相反,有精心设计的类型转换框架,作为"静态接口"的解决方案提到的替代方案之一。矛盾。

但即使考虑到列出的反对意见,在类型系统或语言中缺少一般的解析工具在我看来也是一种尴尬的不对称,因为存在一般的ToString()方法并且非常有用。

在语言/ CLR设计期间曾经讨论过吗?

2 个答案:

答案 0 :(得分:13)

  

System.object类以及.NET中的所有类提供ToString()方法似乎是一个很好的设计决策

也许对你而言。对我来说,这似乎总是一个非常糟糕的主意。

  

,毫不奇怪,返回对象的字符串表示。

是吗?对于绝大多数类型,ToString返回类型的名称。如何对象的字符串表示

不,ToString首先是一个糟糕的设计。它没有明确的合同。除了没有副作用和产生字符串之外,它的语义应该没有明确的指导。

由于ToString没有明确的合同,除了调试器输出之外,几乎没有什么可以安全地使用它。我的意思是,考虑一下:你最后一次在生产代码中调用ToString 对象时是什么时候?我从来没有。

因此,更好的设计可能是static string ToString<T>(T)类上的方法static string ToString(object)Debug。那些可能会产生&#34; null&#34;如果对象为null,或者在T上做了一些反射,以确定是否有该对象的调试器可视化器,等等。

现在让我们考虑一下您的实际提案的优点,这是一般要求所有对象都可以从字符串中反序列化。注意,首先,显然这不是ToString的逆操作。 ToString的绝大多数实现都不会产生任何你甚至可以在理论上用来重构对象的东西。

您的建议是ToString和FromString是否反转?那就要求每个对象不仅仅是代表&#34;作为一个字符串,但它实际上是往返行程序列化到字符串。

让我们想一个例子。我有一个表示数据库表的对象。现在,该表上的ToString是否序列化了表的全部内容? FromString是否反序列化了?假设对象实际上是一个连接器的包装器,它根据需要获取表;我们将什么序列化和反序列化呢?如果连接需要我的密码,它是否将我的密码放入字符串?

假设我有一个引用另一个对象的对象,这样我就不能在没有第二个对象的情况下反序列化第一个对象。序列化是否跨对象递归?那些引用图包含循环的对象呢?我们该如何处理这些?

序列化很困难,这就是为什么整个图书馆都致力于它的原因。要求所有类型都可序列化和反序列化是繁重的。

即使我们想要这样做,为什么字符串的所有东西?字符串是一种糟糕的序列化数据类型。它们不能容易地保存二进制数据,它们必须一次完全存在于内存中,它们不能超过十亿个字符顶部,它们没有结构,等等。您真正想要的序列化是结构化二进制存储系统。

  

但即使考虑到列出的反对意见,在类型系统或语言中缺少一般的解析工具在我看来是一种尴尬的不对称,因为存在一般的ToString()方法并且非常有用。

这是完全不同的两件事,彼此无关。一个是专门针对它的图书馆最好解决的超级硬问题,另一个是一个简单的小调试辅助工具,没有规范限制其输出。

  

在语言/ CLR设计期间曾经讨论过吗?

ToString曾经讨论过吗?显然它是;它得到了实施。是否曾讨论过通用序列化库?显然它是;它得到了实施。我不确定你在这里得到什么。

答案 1 :(得分:10)

  

为什么没有object.ToString()的反转?

因为object应该保留每个对象所需的最低功能。比较相等和转换为字符串(由于很多原因)是其中两个。转换不是。问题是:它应该如何转换?使用JSON?二进制? XML?别的什么?没有一种统一的方法可以从字符串转换。因此,这会不必要地使object类膨胀。

  

或者,至少可以使用IParseable接口

例如:IXmlSerializable或其中一种替代方案。