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

VB vs C#:为什么这是可能的?,c#,vb.net,casting,C#,Vb.net,Casting,这里有一些代码,每次我想到它都会让我感到困扰 选项严格打开 模块1 副标题() 对于新字符串()中作为整数的每个i{“为什么”、“是”、“这个”、“允许?”} “编译得很好。 下一个 端接头 端模块 C#根本不允许将字符串隐式转换为整数 类程序{ 静态void Main(字符串[]参数){ foreach(新字符串[]{“那是”,“更好”}中的int i){ //不会编译,这是有充分理由的。 } } } VB为什么让我们这么做?我试图从中得到乐趣,因为我在这里还是比较新的,但我也很好奇。我肯

这里有一些代码,每次我想到它都会让我感到困扰

选项严格打开
模块1
副标题()
对于新字符串()中作为整数的每个i{“为什么”、“是”、“这个”、“允许?”}
“编译得很好。
下一个
端接头
端模块
C#根本不允许将字符串隐式转换为整数

类程序{
静态void Main(字符串[]参数){
foreach(新字符串[]{“那是”,“更好”}中的int i){
//不会编译,这是有充分理由的。
}
}
}

VB为什么让我们这么做?我试图从中得到乐趣,因为我在这里还是比较新的,但我也很好奇。我肯定有开发人员给出了答案。

这似乎是这句话的一个特点。根据文档,它是在运行时进行评估的

从链接:

当Option Strict设置为On时,缩小转换通常会导致编译器错误。但是,在For-Each语句中,从组中的元素到元素的转换将在运行时进行计算和执行,并且由于缩小转换范围而导致的编译器错误将被抑制

在下面的示例中,当Option Strict处于启用状态时,不会编译m作为n的初始值的赋值,因为从长到整数的转换是一种缩小转换。但是,在For Each语句中,不会报告编译器错误,即使对number的赋值需要从Long到Integer的相同转换。在For Each语句中,当ToInteger应用于较大的数字时,会发生运行时错误


作为对Mark答案的补充,下面是编译后的
vb.net
代码的样子。正如您所看到的,代码被编译成一条语句,只有在运行时尝试将字符串转换为整数时才会发生错误

Dim VB$t_数组$L0 As String()=新字符串(){“为什么”、“是”、“这”、“允许?”}
Dim VB$t_i4$L0作为整数
对于VB$t_i4$L0=0到VB$t_数组$L0.Length-1
Dim i As Integer=Conversions.ToInteger(VB$t_数组$L0(VB$t_i4$L0))
下一个VB$t_i4$L0

Microsoft在语言规范第10.9章:

迭代的当前元素被转换为循环控制变量的类型,即使转换是显式的,因为在语句中没有方便的地方引入转换运算符。在处理最常见的集合类型System.Collections.ArrayList时,这变得特别麻烦,因为它的元素类型是Object。这需要在大量循环中进行强制转换,我们觉得这并不理想。

具有讽刺意味的是,泛型支持创建强类型集合System.Collections.Generic.List(of T),这可能会让我们重新思考这个设计点,但为了兼容性,现在无法更改


我是唯一一个在VB代码中看到数组是一个通用(变量)数组,而C代码包含严格的字符串数组的人吗?

我在文章中包含了
选项strict
语句,它应该限制类型转换为扩大转换,不允许隐式类型,但它仍然可以编译。@mellamokb,正如OP所示,即使在对
选项严格限制的情况下,这也能起作用。这是一个很好的观点。根据即使使用
选项Strict Off
也不应允许对无效数值的字符串进行隐式转换,因此这里一定发生了其他事情。编辑:我刚刚用LINQPad快速测试了这个,但它似乎无法编译。。。你在哪里测试它而没有编译器错误?我想知道这是否是因为,在VB中,“转换”实际上是使用
CType
而不是
DirectCast
完成的,这与C中发生的情况是直接等价的
CType
可以将某些类型的值强制转换为某些其他类型,而
String
转换为
Integer
是受支持的一种组合。这种情况的一个线索是,当您运行代码时,以及当您使用
CType
尝试将非数字的
字符串
转换为
整数时,您在运行时会遇到相同的异常。很好地完成了“出于好奇的问题”这一任务。很有意思,太棒了!谢谢你,马克!我已经更新了代码,使它们都是“严格的字符串数组”。代码仍然没有显示编译时错误。Mark Hall、Bjorn Roger Kringsja和Hans Passant已经提供了足够多的信息来解释为什么会发生这种行为。事实上,如果你看看Bjorn Roger Kringsja的答案,字符串列表最终会变成一个字符串数组。你是如何看到代码变成这样的?我无法在Reflector 8中执行此操作。如果您有桌面应用程序,您应该能够将可执行文件拖放到assembly treeview上。在C#中,所有内容看起来都非常可读。这就是混淆后反编译的样子吗?@scottyeatscode您看到的是转换回vb.net的代码。没有混淆,变量名由编译器自动生成。我不知道使用的确切算法,但例如,对于16位有符号整数(短)和64位有符号整数(长),部分
i4
将变成
i2
。感谢您的解释。我很感激。作为一名开发人员仍在学习和成长。因此,所有这些对我都有好处。:)