繁体   English   中英

与C#相比,VB.NET是弱类型的吗?

[英]Is VB.NET weakly typed compared to C#

昨天我正在接受采访时,我的采访者(不可否认自己并不是这方面的专家)表示“VB.NET比C#的类型更弱” - (同时他也记不起一个例子) )。

这句话对我来说似乎不对(特别是考虑到两种语言都使用相同的框架库作为他们的类型),我这样建议,也许他对选项Strict或Option Infer打开/关闭的选项感到困惑。

与此同时,我知道VB.NET会出现类型强制的情况 - 偶尔导致意外结果(虽然我也无法回想起在什么条件下) - (实际上我想我只是记得它主要是在执行算术运算时使用不同的类型 - 而其他语言将迫使您明确(?))。

那么有人可以澄清一下,VB.NET是否会以某种方式更弱地输入C#,如果是这样,你能举例吗?

如果没有澄清,“弱打字”和“强打字”实际上毫无意义。 它们的使用方式通常意味着“类型系统具有我不喜欢的功能”或“类型系统具有我喜欢的功能”。 听起来你的面试官并不清楚这些术语的含义,因此可能不应该在采访中询问有关他们的问题。

类型系统有很多功能,不同的人说是“强类型”和“弱类型”。 例如,有些人说“强类型”意味着“每个对象在运行时都知道自己的类型”。 有人说“强类型”意味着编译器知道每个变量和表达式的确切类型。 有人说这意味着编译器在每个变量和表达式上都有不精确的类型边界。 等等。 类型系统的每个功能都可以算作“强”的点。

我说放弃整个毫无根据的“强”和“弱”打字概念,并谈谈你的意思。

C#和VB类型系统之间的差异很小,特别是因为向C#4.0添加了“动态”。 C#和VB都使用CLR类型系统,其中每个对象都知道自己的类型,并且运行时检测到非法类型转换(代码运行时或者通过验证程序时),并转换为异常。 两者都具有类的单继承和接口的多继承。 两者都区分了值类型和引用类型。 等等。

C#和VB类型系统之间的主要区别在于VB支持可选地拨打编译时静态类型检查,并将类型检查推迟到运行时,更像是动态类型语言。 当与为动态类型系统设计的对象模型进行互操作时,这非常方便。 我们为C#4.0添加了一个类似的功能,但是为了保持C#4.0对静态类型的历史支持,该功能基于将某些表达式静态键入为“动态”,然后通过在运行时再次启动类型分析器来解决并对活动对象进行类型分析。

有关此主题的更多信息,请访问我的博客:

http://ericlippert.com/2012/10/15/is-ca-strongly-typed-or-a-weakly-typed-language/

作为一种采访策略,最好说“你是正确的,它是更弱的类型,但仅适用于特定设置,如Option Strict Off或Option Infer off”

大多数人更乐意被告知“你是对的”,而不是“你感到困惑”:)

(我之前从未真正使用过VB,所以这对我来说也是新的)

它们指的是Option Strict语句,或者更确切地说当您省略它时会发生什么。

只要你有Option Explicit off,下面的VB就编译并运行perfeclty:

Class Widget
    Sub Method1()

    End Sub
End Class

Sub Main()
    Dim someInt As Integer
    Dim someDouble As Double
    Dim someObj As Object = New Widget

    someDouble = 1234567890.9876542
    someInt = someDouble
    Call someObj.Method1()
    Call someObj.Method2() ' causes runtime error
End Sub

上面隐式地将double转换为整数,在Object引用上调用Method1方法,甚至调用方法Method2 (甚至不存在) - 其中任何一个都不会在C#或VB中用Option Strict On编译。

这绝对符合C#的“不像强类型 ”的定义,尽管该术语似乎相当主观。

更新:我们可以使用ILSpy通过查看已编译的程序集(在C#中)来揭示此处发生的“魔术”:

object obj = new Module1.Widget();
double num = 1234567890.9876542;
int i = Math.Round(num);
NewLateBinding.LateCall(obj, null, "Method1", new object[0], null, null, null, true);
NewLateBinding.LateCall(obj, null, "Method2", new object[0], null, null, null, true);

这解释了为什么VB.Net编译器能够执行在CLR中看起来非法的事情,尽管它似乎确实带来某种运行时性能损失。

VB.NET允许两者。 如评论中所述,您可以通过将Option Strict设置为ON或OFF来在项目(或文件)中设置此项。

这里MSDN文档更多地讨论了该选项的作用。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM