加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

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

发布时间:2020-12-15 20:04:03 所属栏目:百科 来源:网络整理
导读:System.Object类以及因此.NET中的所有类提供ToString()方法似乎是一个很好的设计决策,不出所料,它返回对象的字符串表示.此外,在C#中,此方法是针对本机类型实现的,以便它们与类型系统很好地集成. 当需要用户交互时,这通常会派上用场.例如,对象可以直接保存在
System.Object类以及因此.NET中的所有类提供ToString()方法似乎是一个很好的设计决策,不出所料,它返回对象的字符串表示.此外,在C#中,此方法是针对本机类型实现的,以便它们与类型系统很好地集成.

当需要用户交互时,这通常会派上用场.例如,对象可以直接保存在像列表这样的GUI小部件中,并“自动”显示为文本.

语言设计中没有提供类似通用对象的基本原理是什么.FromString(string)方法?

其他问题和他们的答案讨论了可能的反对意见,但我发现它们并不令人信服.

>解析可能会失败,而转换为字符串始终是可能的.

>那么,这不会使Parse()方法不存在,是吗?如果异常处理被认为是不合需要的设计,那么仍然可以定义一个TryParse()方法,其System.Object的标准实现只返回false,但是对于有意义的具体类型,它被覆盖(例如,此方法存在于今天的类型) ).
>或者,至少有一个IParseable接口可以很好地声明一个ParseMe()或TryParse()方法,沿着ICloneable的路线.

> Tim Schmelter的评论“滚动你自己”:当然是有效的.但我不能为本机类型编写通用代码,或者说,如果必须解析值,则不能编写IPAddress;相反,我不得不求助于类型内省或编写实现自定义接口的包装器,这种接口要么维护不友好,要么单调乏味且容易出错.
> Damien的评论:由于Eric Lippert在here讨论的原因,接口只能声明非静态函数.这是一个非常有效的反对意见.无法在接口中指定静态TryParse()方法.一个虚拟的ParseMe(字符串)方法虽然需要一个虚拟对象,但它最好是一个kludge,最坏的情况下是不可能的(使用RAII).我几乎怀疑这是这种界面不存在的主要原因.相反,有一个复杂的类型转换框架,作为“静态接口”矛盾的解决方案提到的替代方案之一.

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

那是在语言/ CLR设计期间讨论过的吗?

解决方法

It seems like a good design decision that the System.object class,and hence all classes,in .NET provide a ToString() method

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

which,unsurprisingly,returns a string representation of the object.

是吗?对于绝大多数类型,ToString返回类型的名称.那个对象的字符串表示怎么样?

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

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

因此,更好的设计是Debug类上的方法静态字符串ToString< T>(T)和静态字符串ToString(对象).如果对象为null,那么那些可能产生“null”,或者对T进行一些反射以确定是否存在该对象的调试器可视化器,依此类推.

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

那么你的提议是ToString和FromString是反转的吗?那就要求每个对象不仅仅被“表示”为一个字符串,而是它实际上是可以串行化为字符串的往返行程.

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

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

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

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

But even given the objections listed,the absence of a general parsing facility in the type system or language appears to me as an awkward asymmetry,given that a general ToString() method exists and is extremely useful.

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

Was that ever discussed during language/CLR design?

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

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读