VB.. NET弱类型与c#相比

本文关键字:相比 类型 NET VB | 更新日期: 2023-09-27 17:50:26

昨天我参加了一个面试,我的面试官(他显然不是这方面的专家)说:"VB。. NET比c#更弱"——(同时他也想不起一个例子)。

这句话对我来说似乎是不正确的(特别是考虑到两种语言都使用相同的框架库来实现它们的类型),我建议他这样做,也许他混淆了打开/关闭option Strict或option Infer的选项。

同时我知道VB。. NET在某些情况下会进行类型强制转换——偶尔会导致意想不到的结果(尽管我也想不起来是在什么条件下)——(实际上我想我只记得它主要是在对不同类型执行算术运算时——而其他语言会强迫你显式(?))。

所以有人可以澄清是VB。NET在某种程度上比c#更弱类型,如果是的话,你能提供一些例子吗?

VB.. NET弱类型与c#相比

"弱类型"answers"强类型"不加说明实际上是没有意义的。它们的用法通常是指"类型系统有我不喜欢的特性"或"类型系统有我喜欢的特性"。听起来你的面试官对这些术语的含义并不清楚,因此可能不应该在面试中问这些问题。

类型系统有很多不同的人称之为"强类型"answers"弱类型"的特性。例如,有人说"强类型"意味着"每个对象在运行时都知道自己的类型"。有人说"强类型"意味着编译器知道每个变量和表达式的确切类型。有人说,这意味着编译器对每个变量和表达式都有不精确的类型界限。等等......类型系统的每一个特征都可以算作'strong'的点。

我说放弃"强"answers"弱"类型这个毫无根据的概念,谈谈你真正的意思。

c#和VB类型系统之间的差异很少,特别是在c# 4.0中添加了"动态"之后。c#和VB都使用CLR类型系统,在这个系统中,每个对象都知道自己的类型,在这个系统中,非法的类型转换会被运行时检测到(无论是在代码运行时还是在通过验证器时),并转化为异常。两者都具有类的单继承和接口的多继承。两者都区分了值类型和引用类型。等等。

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

关于这个主题的更多信息可以在我的博客上找到:

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

作为一种面试策略,你最好说"你是对的,它是更弱类型的,但只适用于特定的设置,如选项严格关闭或选项推断关闭"

大多数人更愿意听到"你是正确的"而不是"你很困惑":)

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

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

只要关闭Option Explicit,下面的VB编译和运行就会很完美:

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

上面的代码隐式地将双精度类型转换为整数,在Object引用上调用方法Method1,甚至调用方法Method2(它甚至不存在)——这些都不能在c#或VB中使用Option Strict On编译。

这绝对符合c#"不是强类型"的定义,尽管这个术语似乎是相当主观的。

Update:我们可以使用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文档详细介绍了该选项的作用