.Net从ToString中抛出异常?

时间:2010-08-02 23:39:40

标签: c# exception tostring

好奇是否有人对我的重写ToString实现中抛出异常有任何意见。我的直觉告诉我这可能是不好的做法,但如果这是坏事,我似乎无法找到任何支持。

有什么想法吗?

代码:http://pastebin.com/mLEkBAAz

感谢。

7 个答案:

答案 0 :(得分:8)

我不会这样做。我没有看到任何情况下使用ToString()方法抛出异常而不是例如返回Object.ToString()字符串的表示更好。

您通常会使用大量.ToString()调用进行调试。 现在,假设您正在调试代码并尝试捕获错误。您的错误代码不仅会在随机位置抛出异常,您还必须处理让对象的字符串表示抛出异常的附加问题。

编辑:

所以,通过你告诉我们的, 我可能不会把你放在.ToString()的代码放进去。我会找到另一个方法名称,比方说.GetXMLRepresentation(),我还有一个.CheckIfIsInValidState()。然后,如果你试图以无效状态调用它,我会使.GetXMLRepresentation()抛出异常。但是我想将.ToString()用于其他目的。

答案 1 :(得分:6)

对象永远不应处于无效状态。一旦消费者试图在其上设置无效状态,该对象就应抛出异常。

你的对象可能处于不可用的状态(比如它是一个数据库连接对象,它还没有连接),在这种情况下它应该有一个IsConnected标志,或者它应该遵循state machine pattern以便对象的状态本身仍然有效。

因为你的ToString()重载可能不会带任何参数,所以它不应该是调用者的错误,它会引发异常。

因此,不,我想不出ToString()会抛出的任何异常。

编辑:对于pastebin代码,执行此操作的最佳方法是将查询参数合并到一个单独的类中 - 将其称为SearchParameters或其他类。

首先填充它,然后将其传递给一个将生成SQL代码的类。如果将SearchParameters对象传递给SearchQuery(可能通过构造函数使其可以使其不可变)参数无效,则可以在那里抛出异常。

这样,如果你的SearchQuery对象有更多依赖于有效搜索查询的方法,你就不需要重复验证代码了,当然,ToString()永远不会抛出异常。

答案 2 :(得分:2)

Gendarme(静态分析工具)有"Do Not Throw In Unexpected Location" rule表示:

  

Object.ToString - 这些由调试器调用以显示对象,并且通常也用于printf样式调试,因此它们不应该更改对象的状态而不应该抛出。

微软几乎没有官方,但这是一个非常好的指标,即投入ToString方法是不好的做法。

答案 3 :(得分:0)

如果对象处于无效状态,则应抛出异常。如果我看到像NullReferenceException这样的东西,那么我只想说我不会留下深刻的印象。

我的理念是,我不够聪明,无法涵盖所有​​案例,所以我抛出异常来帮助自己和其他程序员尽早发现错误。也称为快速失败理念。

答案 4 :(得分:0)

我说这是个坏主意。如果对象处于无效状态,那么它必须有一些点 - 这就是你应该抛出的地方,而不是当你将它转换为字符串时。 IMO,任何对象都应该始终具有有效的字符串表示形式,即使它是默认的后退(对象的类名)。

答案 5 :(得分:0)

异常是object的{​​{1}}方法的合同的一部分,因此,派生类实现抛出的任何异常都不应该与基类实现抛出的异常不同,在我看来。我不认为ToString在任何Microsoft基本BCL类中抛出任何类型的异常,所以我坚持使用该约定。

如你所说,如果抛出任何其他异常,那将是一个惊喜。程序员不喜欢惊喜。

答案 6 :(得分:0)

ToString()是一个像任何其他方法一样的方法,所以如果你想在执行时报告一个问题,你应该抛出异常(像往常一样,不要使用异常来表达逻辑或返回结果)。如果elysium提到调试成为问题,你可以用DebuggerStepThrough属性标记ToString()方法。