.Net 从 ToString 抛出异常?
只是好奇是否有人对在我重写的 ToString 实现中抛出异常有任何意见。我的直觉告诉我这可能是不好的做法,但我似乎无法找到任何支持这是否不好的证据。
有什么想法吗?
代码:http://pastebin.com/mLEkBAAz
谢谢。
Just curious if anyone has any opinions on throwing an exception in my overridden ToString implementation. My instincts tell me this might be bad practice, but I don't seem to be able to find anything supporting if this is bad or not.
Any thoughts?
Code: http://pastebin.com/mLEkBAAz
Thanks.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
我不会这么做。我没有看到任何情况下,让
ToString()
方法抛出异常而不是返回Object.ToString()
字符串会更好。表示。您通常会使用大量 .ToString() 调用来进行调试。
现在,假设您正在调试代码并尝试捕获错误。有缺陷的代码不仅会在随机位置抛出异常,而且还必须处理对象的字符串表示抛出异常的额外问题。
编辑:
所以,根据你告诉我们的,
我可能不会将您放入的代码放入
.ToString()
中。我会找到另一个方法名称,比如说.GetXMLRepresentation()
,并且我还有一个.CheckIfIsInValidState()
。然后,如果您尝试在无效状态下调用它,我会让.GetXMLRepresentation()
抛出异常。但我想将.ToString()
用于其他目的。I wouldn't do it. I don't see any situation where it would be better to have a
ToString()
method throw an exception instead of, for instance, returning theObject.ToString()
string's representation.You generally use a lot of .ToString() calls for debugging purposes.
Now, let's say you're debugging your code and trying to catch a bug. Not only is your buggy code throwing exceptions in random places, you also have to take care of the aditional problem of having object's string representations throwing exceptions.
Edit:
So, by what you're telling us,
I probably wouldn't put the code you are puting in
.ToString()
's. I'd find another method name, let's say,.GetXMLRepresentation()
and I'd have also a.CheckIfIsInValidState()
. Then, I'd make.GetXMLRepresentation()
throw an exception if you tried to call it in an invalid state. But I'd like to use.ToString()
for other kind of purposes.对象永远不应该处于无效状态。一旦消费者尝试在对象上设置无效状态,该对象就应该抛出异常。
您的对象可能处于不可用状态(假设它是一个数据库连接对象,并且尚未连接),在这种情况下,它应该有一个 IsConnected 标志,或者它应该遵循 状态机模式,以便对象的状态本身仍然有效。
而且由于您的 ToString() 重载可能不接受任何参数,因此抛出异常绝不应该是调用者的错误。
因此,不,我想不出 ToString() 会抛出任何异常。
编辑:对于 Pastebin 代码,执行此操作的最佳方法是将查询参数合并到一个单独的类中 - 称之为 SearchParameters 或其他类。
首先填充它,然后将其传递到将生成 SQL 代码的类中。如果当您将 SearchParameters 对象传递到 SearchQuery 时(可能通过构造函数,以便使其不可变),参数无效,您可以在那里抛出异常。
这样,如果您的 SearchQuery 对象有更多依赖于有效搜索查询的方法,您将不需要重复验证代码,当然,ToString() 永远不会抛出异常。
An object should never be in an invalid state. The object should throw an exception as soon as the consumer tries to set an invalid state on it.
Your object could be in an unusable state (say it's a database connection object, and it hasn't connected yet), in which case it should have an IsConnected flag, or it should follow the state machine pattern so that the object's state is still valid in its own right.
And since your ToString() overload presumably doesn't take any arguments, it should never be the caller's fault that it would throw an exception.
Therefore, no, I can't think of any exceptions that ToString() would throw.
Edit: In the case of the pastebin code, the best way to go about doing this would be to consolidate the query parameters in a separate class -- call it SearchParameters or something.
Populate that first, and then pass that into a class that'll generate the SQL code. If when you pass the SearchParameters object into SearchQuery (probably through the constructor so that you can make it immutable) the parameters are invalid, you can throw an exception there.
That way if your SearchQuery object ever has more methods that rely on there being a valid search query, you won't need to repeat the validation code, and of course, ToString() will never throw an exception.
Gendarme(静态分析工具)有一个 “不要扔到意外位置”规则 指出:
Microsoft 几乎没有正式发布,但这是一个非常好的指标,表明引入
ToString
方法是一种糟糕的做法。Gendarme (a static analysis tool) has a "Do Not Throw In Unexpected Location" rule that states:
Hardly official by Microsoft, but this is a very good indicator that it would be poor practice to throw in a
ToString
method.我想说这是一个坏主意。如果对象处于无效状态,则必须在某个点到达该状态 - 这就是您应该抛出的位置,而不是在将其转换为字符串时。 IMO,任何对象都应该始终具有有效的字符串表示形式,即使它是默认的后备(对象的类名)。
I'd say it's a bad idea. If the object is in an invalid state, there must be some point at which it got there - that's where you should throw, not when you convert it to string. IMO, any object should have a valid string representation at all times, even if it's the default fall-back (the object's class name).
如果对象处于无效状态,您应该抛出异常。如果我看到类似
NullReferenceException
的东西,那么我只能说我不会留下深刻的印象。我的理念是,我不够聪明,无法涵盖所有情况,因此我抛出异常来帮助自己和其他程序员及早发现错误。也称为快速失败理念。
If the object is in an invalid state you should throw an exception. If I see something like a
NullReferenceException
, well lets just say I won't be impressed.My philosophy is that I am not smart enough to cover all cases so I throw exceptions to help myself and other programmers catch errors early. Also known as the Fail Fast philosophy.
异常是
object
的ToString
方法协定的一部分,因此,派生类实现引发的任何异常不应与基类实现引发的异常不同,在我看来。我认为ToString
不会在任何 Microsoft BCL 基类中引发任何类型的异常,因此我会遵守该约定。正如你所说,如果抛出任何其他异常,那将是一个惊喜。程序员不喜欢惊喜。
Exceptions are part of the contract of
object
'sToString
method and, as such, any exceptions thrown by derived class implementations should not differ to those thrown by the base class implementation, in my opinion. I don't thinkToString
throws any kind of exception in any of the Microsoft base BCL classes, so I'd stick to that convention.As you said, if any other exception is thrown, it will be a surprise. Programmers don't like surprises.
ToString() 是一个与其他方法一样的方法,因此如果您想报告其执行中的问题,您应该抛出异常(像往常一样,不要使用异常来表达逻辑或返回结果)。如果,如 elysium 提到的,调试出现问题,您可以使用 DebuggerStepThrough 属性标记 ToString() 方法。
ToString() is a method like any other, so if you want to report a problem in its execution you should throw an exception (as usual, don't use exceptions for expressing logic or returning results). If, as elysium mentions, debugging becomes problematic you can mark the ToString() method with the DebuggerStepThrough attribute.