向下转换(即转换为派生类型)总是错的?

时间:2010-02-14 20:48:53

标签: oop

您对向下转型的看法是什么?它是否总是错误的,或者是否存在可接受的情况,甚至是可取的还是需要的?

我们可以给出一些好的衡量标准/指导方针,告诉我们什么时候预测是“邪恶的”,什么时候“好”/“好”?

(我知道a similar question exists,但这个问题从一个具体案例中消失了。我想从一般设计的角度来回答。)

3 个答案:

答案 0 :(得分:8)

不,它绝对不是总是错误。

例如,假设在C#中你有一个事件处理程序 - 它被赋予一个sender参数,代表事件的发起者。现在您可以将该事件处理程序连接到多个按钮,但您知道它们始终是按钮。在该代码中将sender转换为Button是合理的。

这只是一个例子 - 还有很多其他的例子。有时它仅仅是一种略微笨拙的API的方法,有时它是因为无法在普通类型系统中干净地表达类型。例如,您可能具有适当的Dictionary<Type, object>封装,使用通用方法来添加和检索值 - 其中条目的值是键的类型。演员阵容在这里是完全自然的 - 你可以看到它总是有效,并且它为系统的其他部分提供了更多类型的安全性。

答案 1 :(得分:3)

这绝不是理想的解决方案,应尽可能避免 - 除非替代方案会更糟。有时,无法避免,例如pre-Generics Java的标准API库有许多类(最突出的是集合),它们需要向下转换才有用。有时,改变设计以避免向下转换会使其显着复杂化,因此向下转换是更好的解决方案。

答案 2 :(得分:1)

“合法”向下转换的一个示例是Java pre 5.0,在访问它们时,您必须将容器元素向下转换为具体类型。在这种情况下,这是不可避免的。这也显示了问题的另一面:如果你需要在特定情况下投降,它开始是邪恶的,所以最好找到另一个没有向下转换的解决方案。这导致在Java 5中引入了泛型。

John Vlissides在他出色的着作Pattern Hatching(实际上是Design Patterns的续集)中分析了这个问题(又名“洗钱”)。