是否有借口从隐式转换中抛出异常?
来自 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:显然不行。 永远不要使用异常来实现逻辑!
您可以使用 Linq 语句
FooCollection.FirstOrDefault()
,它将给出 null 或第一项。It clearly is not OK. Never ever use exceptions to implement logic!
You may use the Linq-Statement
FooCollection.FirstOrDefault()
, which will give null or the first item.演员阵容应该是明确的。能够将
FooCollection
分配给Foo
而无需至少进行强制转换,这将是非常奇怪的。话虽这么说,恕我直言,演员阵容并不是一个好方法。即使你拒绝它,我也会使用一个函数,因为即使你无法控制这些类的实现,你至少可以添加扩展方法,例如
Foo ToFoo(this FooCollection collection)
完成工作。The cast should be explicit. It'll be very strange to be able to assign a
FooCollection
to aFoo
without at least a cast.That being said, IMHO casts are not a good way to do this. Even if you say no to it I'll use a function because even if you don't have control over the implementation of these classes, you can at least add Extensions Methods like
Foo ToFoo(this FooCollection collection)
to get the job done.仅当集合中只有 1 项时才起作用的隐式 copnversion?那么,事实上,它在大多数时候都不起作用?
我永远不会隐式进行这种转换。坚持明确。如果使用你的函数的程序员想要拥有单个项目,他应该告诉你的类。
An implicit copnversion that does only work if there is just 1 item in the collection? So, in fact, it doesn't work most of the time?
I would never make this conversion implicit. Stick with explicit. If the programmer using your function wants to have the single item, he should just tell your class.