我对vb.net相当陌生,在将C#中的for循环转换成VB.net时遇到了这个问题。我意识到在vb.net中没有增量运算符(++和--),但我可以像cnt += 1
这样做。
我进行了一些研究并找到了Eric的文章,但并没有完全理解其中的内容。 他提到在VB中,语句不能只是一个表达式。不确定它实际上是如何契合的。
我希望有人能够解释为什么这种方法在VB中不能像在C#中那样工作。(希望这也适用于为什么C#中有==
用于比较)
我对vb.net相当陌生,在将C#中的for循环转换成VB.net时遇到了这个问题。我意识到在vb.net中没有增量运算符(++和--),但我可以像cnt += 1
这样做。
我进行了一些研究并找到了Eric的文章,但并没有完全理解其中的内容。 他提到在VB中,语句不能只是一个表达式。不确定它实际上是如何契合的。
我希望有人能够解释为什么这种方法在VB中不能像在C#中那样工作。(希望这也适用于为什么C#中有==
用于比较)
我认为在设计Visual BASIC时,语言设计者只是认为BASIC比C更好作为基准。你可以通过追溯C++
、Java
和C#
的谱系来了解C
(以及早期的BCPL
)。
VB
的谱系源自Dartmouth的原始BASIC
(以及早期的Fortran
),完全是另一回事。
换句话说,最初的崇高BASIC
:
LET I = I + 1
大概已经被黑客攻击和破坏了足够 :-)
根据Eric的帖子,i++;
确实只是一个表达式,它产生了i
这个值并在事件之后使i
增加(类似于没有副作用的表达式i;
)。
这是因为C语言
允许这些裸露的表达式,即使像42;
这样的事情也不会有太多影响但是完全有效。换句话说,以下是一个完整的C语言
程序:
int main (void) { 1; 2; 3; 4; 5; 6; 7; 8; 9; return 0; }
所有这些表达式都是有效的但是没有用(当然除了末尾的0
)。i += 1
(增加i
的语句)被认为是可以的,但i++
(一个不做任何事情,只是具有副作用增加i
的表达式)不行。你可以争辩说这只是纠结于语义,但它就是这样。ADD 1 TO DD_WS_I.
设计师认为当你有i += 1时,i++是不必要的。
for
循环也不需要这两个操作符,所以你不会失去任何东西。
毕竟这是Visual Basic...为什么要把它搞得复杂呢?
i += 1
,而在 C++ 中,++i
和 i += 1
可以是更大表达式的一部分(例如 a[++i] = (b += 2);
)。 - NetMage正如 @paxdiablo 所说,在 VB(或者更准确地说,在其祖先 BASIC 中),所有的东西都是一条语句。实际上,每条语句都由一个关键字引入。
因此,要分配一个变量,我们使用以下语法:
LET x = x + 1
要调用一个方法,我们需要
CALL SomeMethod
LET
和CALL
被最终取消了(除了一种特殊情况),因为它完全是多余的,而且不会增加清晰度。但是VB的底层词汇语法并没有改变太多:每个语句仍然必须是一个语句。在VB中,i++
不是一个语句,因为它缺少函数调用或赋值。
在第一个VB.NET版本中曾经存在过一个争论,即是否像C#那样引入前置和后置增量运算符。出于一个非常简单的原因,决定不这样做:在表达式中使用副作用并不推荐。通常会降低清晰度。所以即使在C#中,在表达式中合法使用i++
是非常罕见的,而对++i
的合法使用更加罕见(尽管我不会否认在某些情况下它可以增加清晰度)。
在大多数情况下,你可以很好地使用i += 1
来表达意图。
请注意,在C++中,情况基本上是不同的,因为这里(但在C#中不是!)i++
实际上具有不同的语义,因为它涉及到运算符重载(在C#中我们也有运算符重载,但++
不能被重载)。
Dim count As Integer = 0
Console.WriteLine(count += 1) ' compiler error
你需要做这个而不是那个
Dim count As Integer = 0
count += 1
Console.Writeline(count)
+=
运算符。 2 + 2
产生结果 4
,可以作为语句独立存在,而在VB中则不行。count ++
表示,“首先”返回 count
的值,“然后”使 count
增加1(并不返回 count
的赋值结果)。 ++ count
表示,“首先”使 count
增加1,“然后”返回 count
的赋值结果。 count
的值作为表达式的值返回。如前所述,在VB中赋值不会产生结果。++x
x++
--x
x--
的功能。Public Module INC_DEC
<Runtime.CompilerServices.Extension>
Public Function PreINC(ByRef x As Integer) As Integer
Return Interlocked.Increment(x)
End Function
<Runtime.CompilerServices.Extension>
Public Function PostINC(ByRef x As Integer) As Integer
Dim tmp = x
Interlocked.Increment(x)
Return tmp
End Function
<Runtime.CompilerServices.Extension>
Public Function PreDEC(ByRef x As Integer) As Integer
Return Interlocked.Decrement(x)
End Function
<Runtime.CompilerServices.Extension>
Public Function PostDEC(ByRef x As Integer) As Integer
Dim tmp = x
Interlocked.Decrement(x)
Return tmp
End Function
End Module