是否有借口从隐式转换中抛出异常?
来自 MSDN:
通过消除不必要的转换,隐式转换可以提高源代码的可读性。但是,由于隐式转换可能会在程序员不指定的情况下发生,因此必须小心防止出现令人不快的意外情况。一般来说,隐式转换运算符不应该抛出异常,也不应该丢失信息,这样就可以在程序员不知情的情况下安全地使用它们。如果转换运算符不能满足这些条件,则应将其标记为显式。
虽然我不同意任何特定观点,并且我同意这一切都非常好,但是否有一个足够大的理由可以保证打破有关隐式转换不抛出异常的部分?
我面前的特殊情况是:
- 我有一个函数,它返回一个自定义集合对象(我们将其称为
FooCollection
)。 - 该函数可以返回包含单个项目的集合,并且可以从源代码中确定是否会发生这种情况。 (我的意思只是函数调用,而不是函数本身)
- 如果确实发生,则 99.9% 的可能是用户想要该单个项目,而不是包含单个项目的集合。
现在,我正在犹豫是否要包含来自 FooCollection
=> 的隐式转换。 Foo
来隐藏这个小实现细节,但这种转换仅在集合中只有单个项目时才有效。
在这种情况下可以抛出Exception
吗?或者我应该使用显式强制转换?关于如何处理这个问题的任何其他想法(不,由于实现细节,我不能只使用两个函数)?
编辑:我觉得值得注意的是,FooCollection
没有实现任何接口,也没有实际扩展Collection
,正如名称所暗示的那样,因此LINQ基于的答案是没有用的。此外,虽然集合确实实现了数字索引,但这并不是处理集合的最直观的方式,因为它主要依赖于命名索引。
From MSDN:
By eliminating unnecessary casts, implicit conversions can improve source code readability. However, because implicit conversions can occur without the programmer's specifying them, care must be taken to prevent unpleasant surprises. In general, implicit conversion operators should never throw exceptions and never lose information so that they can be used safely without the programmer's awareness. If a conversion operator cannot meet those criteria, it should be marked explicit.
While I don't disagree with any particular point, and I agree that this is all very good, is there ever a reason that is great enough to warrant breaking the part about implicit conversions not throwing exceptions?
The particular case I have before me is one where:
- I have a function, which returns a custom collection object (we'll call it
FooCollection
). - This function can return collections with a single item, and it can be determined from the source code whether this will happen or not. (by this I mean just the function call, not the function itself)
- If it does happen, it is 99.9% likely that the user wants that single item, rather than a collection with a single item.
Now, I'm tossing up whether to include an implicit conversion from FooCollection
=> Foo
to hide this little implementation detail, but this conversion will only work if there is a single item in the collection.
Is it ok to throw an Exception
in this case? Or should I be using an explicit cast instead? Any other ideas about how I could deal with this (no, due to implementation details I can't just use two functions)?
EDIT: I feel it worthy of noting that FooCollection
doesn't implement any interfaces or actually extend Collection
as the name might imply, hence the LINQ based answers are useless. Also, while the collection does implement a numeric index, it isn't the most intuitive way of dealing with the collection as it relies on named index mostly.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
发布评论
评论(4)
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
我同意以下准则:您不应该从隐式转换中抛出异常。
在这种情况下我绝对不会提供隐式转换。即使是显式强制转换的想法对我来说也是错误的:
Foo x = (Foo)fooCollection
似乎不太正确。为什么不让调用代码担心从
FooCollection
到Foo
的转换呢?代码对每个人来说都会更加直观:I'm with the guidelines: You shouldn't ever throw from an implicit conversion.
I definitely wouldn't provide an implicit conversion in this case. Even the idea of an explicit cast feels wrong to me:
Foo x = (Foo)fooCollection
just doesn't seem right.Why don't you just let the calling code worry about the conversion from
FooCollection
toFoo
? The code would be much more intuitive for everyone: