VB vs C#:为什么这可能?

sco*_*ode 22 c# vb.net casting

这是一些代码,每当我想到它时都会给我带来麻烦.

Option Strict On

Module Module1

    Sub Main()
        For Each i As Integer In New String() {"why", "is", "this", "tolerated?"}
            ' compiles just fine.
        Next
    End Sub

End Module
Run Code Online (Sandbox Code Playgroud)

C#根本不允许隐式地将字符串转换为整数.

class Program {
    static void Main(string[] args) {
        foreach (int i in new string[] {"that's", "better"}) {
            // will not compile, and for good reason.
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

为什么VB让我们这样做?我正试着玩这个,因为我在这里还比较新,但我也很好奇.我确信那里有开发人员的答案.

Mar*_*all 14

它似乎是该For Each声明的特质.根据文档,它在运行时进行评估.

来自Link:

当Option Strict设置为On时,缩小转换通常会导致编译器错误.但是,在For Each语句中,将在运行时评估并执行从组中的元素到元素的转换,并抑制由缩小转换引起的编译器错误.

在下面的示例中,当Option Strict打开时,m的分配作为n的初始值不会编译,因为Long转换为Integer是一个收缩的转换.但是,在For Each语句中,即使对数字的赋值需要从Long到Integer的相同转换,也不会报告编译器错误.在包含大数的For Each语句中,将ToInteger应用于大数时会发生运行时错误.

  • 哇 - 就在我以为我已经看到了这一切,就像VB的怪异一样...... (8认同)
  • 优秀!谢谢,马克! (2认同)

Han*_*ant 11

Microsoft在语言规范第10.9章中为此道歉:

即使转换是显式的,迭代的当前元素也会转换为循环控制变量的类型,因为在语句中没有方便的位置引入转换运算符.当使用最常见的集合类型System.Collections.ArrayList时,这变得特别麻烦,因为它的元素类型是Object.这将需要在很多循环中进行演员表演,我们觉得这并不理想.

具有讽刺意味的是,泛型启用了强类型集合System.Collections.Generic.List(Of T)的创建,这可能让我们重新考虑这个设计点,但出于兼容性的考虑,现在无法改变.


Bjø*_*sjå 6

作为Mark答案的补充,这里是编译vb.net代码的样子.正如您所看到的,代码被编译为For ... Next语句,并且只有在尝试将字符串转换为整数时才会在运行时发生错误.

Dim VB$t_array$L0 As String() = New String() { "why", "is", "this", "tolerated?" }
Dim VB$t_i4$L0 As Integer
For VB$t_i4$L0 = 0 To VB$t_array$L0.Length - 1
    Dim i As Integer = Conversions.ToInteger(VB$t_array$L0(VB$t_i4$L0))
Next VB$t_i4$L0
Run Code Online (Sandbox Code Playgroud)