好奇是否有人对我的重写ToString实现中抛出异常有任何意见。我的直觉告诉我这可能是不好的做法,但如果这是坏事,我似乎无法找到任何支持。
有什么想法吗?
代码:http://pastebin.com/mLEkBAAz
感谢。
答案 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()方法。