我仍然需要处理Visual Basic 6。
我刚刚发现对象类型的对应关系仅在运行时强制执行。请参阅示例this question。
我很震惊地发现这一点,我总是依赖对象的类型安全检查。
有人知道是否存在这样的架构原因(至少使其成为一个复杂的问题)?
如果涉及到多态,我会理解它,但是当参数的类型是一个没有被其他任何实现的类时,我在编译时看不到类型检查中的任何问题......?
答案 0 :(得分:4)
历史课
VB版本1到3 更严格。类型一致性检查仍在运行时进行,但更严格。如果将字符串分配给整数,则会出现运行时错误。我不知道为什么只在运行时进行一致性检查 - 猜测编译时检查更难以实现。
在VB版本4 中,语言已更改,以便(例如)将字符串分配给整数不会引发错误,但会隐式将字符串值转换为整数。例如,如果包含"0"
或""
的字符串将转换为0
。如果包含字符串,比如"1E40"
,则会出现溢出错误。许多VB程序员(包括,呃,我)讨厌这种变化,称之为邪恶类型强制。例如。由大师卡尔彼得森看这article。
所以架构方法是"尝试通过猜测在运行时转换类型,只有在不可能时才会引发错误"。这意味着,检查有在运行时进行。我原则上假设编译器可以检测到对象类型是私有的,而不是由任何其他类实现的情况,并在编译时检查,但我想这不是编译器开发人员的优先级。甚至可能让开发人员难以理解为什么在运行时检查某些赋值以及在编译时检查其他赋值。
在VB.Net中,默认行为与VB6相同,以便更容易升级旧代码。在VB.Net中首选Option Strict On
,以便在编译时完成检查。编译时检查很有用,因为它们会提前标记错误。
答案 1 :(得分:2)
仅实现接口,而不是类。 VB6类Car
隐式定义了可以在任何外部项目(DLL)中实现的接口_Car
,并且可以与任何其他接口捆绑在一个coclass上(包括_Boat
)
如果Dim c As Car
是编译器使用的接口_Car
,那么c
可以在任何对象上保存对_Car
接口的引用,而不仅仅是Car
类的实例。例如。您可以编写实现Mix
和_Car
接口的coclass _Boat
,因此Set c = New Mix
编译并运行,因此在Sail c
中{{1}的QI接口实际上成功了(想想"演员"成功)。
请注意,这不是upcast,也不是downcast,因为_Boat
和_Car
不受任何继承形式的约束。但这是COM允许您通过_Boat
接口实现的。
在现代语言中,他们决定你总是要求在代码中明确地向下转换(否则会出现编译错误),并且与#34; side-casts"相同。 (如在人为设计的汽车/船上的例子),不要在腿上射击自己。