是否有借口从隐式转换中抛出异常?

时间:2009-10-08 11:55:28

标签: c# casting implicit explicit

来自MSDN

  

通过消除不必要的强制转换,隐式转换可以提高源代码的可读性。但是,因为隐式转换可以在程序员指定它们的情况下发生,所以必须注意防止令人不快的意外。通常,隐式转换运算符不应该抛出异常并且永远不会丢失信息,以便在没有程序员意识的情况下可以安全地使用它们。如果转换运算符不符合这些条件,则应将其标记为显式。

虽然我并不反对任何特定的观点,并且我同意这一切都非常好,但有没有理由足以让我们打破关于隐式转换而不是抛出异常的部分?

我面前的具体案例是:

  1. 我有一个函数,它返回一个自定义集合对象(我们称之为FooCollection)。
  2. 此功能可以使用单个项目返回集合,可以从源代码确定是否会发生这种情况。 (我的意思是函数调用,而不是函数本身)
  3. 如果确实发生了这种情况,那么用户想要单个项目的可能性为99.9%,而不是具有单个项目的集合。
  4. 现在,我正在讨论是否包含来自FooCollection =>的隐式转换。 Foo隐藏这个小实现细节,但只有在集合中有一个项目时,此转换才有效。

    在这种情况下可以抛出Exception吗?或者我应该使用显式转换?关于我如何处理这个的任何其他想法(不,由于实现细节,我不能只使用两个函数)?

    编辑:我觉得值得注意FooCollection没有实现任何接口或实际扩展Collection,因为名称可能暗示,因此基于LINQ的答案是无用。此外,虽然集合确实实现了数字索引,但它并不是处理集合的最直观方式,因为它主要依赖于命名索引。

4 个答案:

答案 0 :(得分:10)

我遵守指导原则:你不应该从隐式转换中抛弃。

在这种情况下,我绝对不会提供隐式转换。即使是明确演员的想法对我来说也是错的:Foo x = (Foo)fooCollection似乎不对。

为什么不让调用代码担心从FooCollectionFoo的转换?代码对每个人来说都更加直观:

Foo a = fooCollection[0];
Foo b = fooCollection.First();
Foo c = fooCollection.FirstOrDefault();
// etc

答案 1 :(得分:1)

显然不行。 永远不会使用异常来实现逻辑!

您可以使用Linq-Statement FooCollection.FirstOrDefault(),它将提供null或第一项。

答案 2 :(得分:0)

演员阵容应该是明确的。能够在没有至少演员的情况下将FooCollection分配给Foo会非常奇怪。

话虽如此,恕我直言的演员并不是一个很好的方法。即使你对它说不,我也会使用一个函数,因为即使你无法控制这些类的实现,你至少可以添加像Foo ToFoo(this FooCollection collection)这样的扩展方法来完成工作。

答案 3 :(得分:0)

隐式copnversion只有在集合中只有1个项目时才有效吗?那么,事实上,它大部分时间都不起作用?

我永远不会隐含这种转换。坚持明确。如果使用你的函数的程序员想要单个项目,他应该告诉你的班级。