VB.net 中没有增量运算符

35

我对vb.net相当陌生,在将C#中的for循环转换成VB.net时遇到了这个问题。我意识到在vb.net中没有增量运算符(++和--),但我可以像cnt += 1这样做。

我进行了一些研究并找到了Eric的文章,但并没有完全理解其中的内容。 他提到在VB中,语句不能只是一个表达式。不确定它实际上是如何契合的。

我希望有人能够解释为什么这种方法在VB中不能像在C#中那样工作。(希望这也适用于为什么C#中有==用于比较)


-1,这似乎又是另一个VB.NET抨击会议? - Predator
4
@Gens 这不是攻击,我只是对为什么感兴趣。 - V4Vendetta
6
你提供的链接文章中已经解释了原因。我认为你不可能得到比那更接近的答案了。 - Sven
Python也是同样的道理。基本上,它允许更简单、更易于解析的代码,并有助于防止神秘的一行代码或意外的行为。 - James O'Doherty
5个回答

45

我认为在设计Visual BASIC时,语言设计者只是认为BASIC比C更好作为基准。你可以通过追溯C++JavaC#的谱系来了解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)。
在BASIC中,这并不是真正的做法,因为BASIC由语句(执行某些操作的东西)组成。这就是为什么i += 1(增加i的语句)被认为是可以的,但i++(一个不做任何事情,只是具有副作用增加i的表达式)不行。你可以争辩说这只是纠结于语义,但它就是这样。
你应该为小恩惠感到感激,至少你不必处理COBOL:
ADD 1 TO DD_WS_I.

好的。您能否强调一下为什么它与语句和表达式有关(对不起,我对VB的知识非常有限,请建议我是否没有特别的VB背景)? - V4Vendetta
2
我不太确定我是怎么偶然发现这个问题的,但是你的回答很棒。 - basher
肯定地将 LS-VAL-01 加到 WS-VAL-DD 中并将结果存入 WS-VAL-DD-NEW。或者更好的做法是使用 COMPUTE ... GIVING。 - David Shields
我正在处理VB.NET和COBOL。 - nardnob

10

设计师认为当你有i += 1时,i++是不必要的。

for循环也不需要这两个操作符,所以你不会失去任何东西。

毕竟这是Visual Basic...为什么要把它搞得复杂呢?


他们没有考虑到C#的情况吗? - V4Vendetta
6
@V4Vendetta:不是的,因为它被设计成类似于C/C++。 - user541686
2
我不同意 - 你不能在任何表达式上下文中使用 i += 1,而在 C++ 中,++ii += 1 可以是更大表达式的一部分(例如 a[++i] = (b += 2);)。 - NetMage

6

正如 @paxdiablo 所说,在 VB(或者更准确地说,在其祖先 BASIC 中),所有的东西都是一条语句。实际上,每条语句都由一个关键字引入。

因此,要分配一个变量,我们使用以下语法:

LET x = x + 1

要调用一个方法,我们需要

CALL SomeMethod

在VB中,LETCALL被最终取消了(除了一种特殊情况),因为它完全是多余的,而且不会增加清晰度。但是VB的底层词汇语法并没有改变太多:每个语句仍然必须是一个语句。在VB中,i++不是一个语句,因为它缺少函数调用或赋值。

在第一个VB.NET版本中曾经存在过一个争论,即是否像C#那样引入前置和后置增量运算符。出于一个非常简单的原因,决定不这样做:在表达式中使用副作用并不推荐。通常会降低清晰度。所以即使在C#中,在表达式中合法使用i++是非常罕见的,而对++i的合法使用更加罕见(尽管我不会否认在某些情况下它可以增加清晰度)。

在大多数情况下,你可以很好地使用i += 1来表达意图。

请注意,在C++中,情况基本上是不同的,因为这里(但在C#中不是!)i++实际上具有不同的语义,因为它涉及到运算符重载(在C#中我们也有运算符重载,但++不能被重载)。


5
作为VB中表达式和语句之间差异的一个例子,在VB中以下内容会产生编译错误,因为count += 1会将count加1,但整个表达式count += 1没有返回结果,所以无法作为参数使用。
Dim count As Integer = 0
Console.WriteLine(count += 1)  ' compiler error

你需要做这个而不是那个

Dim count As Integer = 0
count += 1
Console.Writeline(count)

当然,这也适用于在字符串上使用 += 运算符。
“在VB中,语句不能仅仅是表达式”是什么意思?
  • VB编译器要求结果在某个赋值或其他操作中被使用。
  • 因此,在VB中的赋值操作不会产生结果。如果它产生结果,VB编译器不允许它单独作为语句存在(编译器要求消耗结果)。
  • 因此,在VB中,可以将赋值用作语句,但不能将其用作表达式。也就是说,您不能将赋值语句用作方法参数或中间结果。
  • 在C#中,赋值操作会产生一个值。因此,为了让赋值独立成为语句,编译器不需要消耗所有的结果。
  • C#中的推论是,任何产生结果的其他操作都可以独立成为语句。例如, 2 + 2 产生结果 4 ,可以作为语句独立存在,而在VB中则不行。
对于“为什么VB中没有前置和后置自增运算符”的简化答案: count ++ 表示,“首先”返回 count 的值,“然后”使 count 增加1(并不返回 count 的赋值结果)。
在这种情况下,增加后的值没有被使用(使用增加前的值)。如前所述,VB编译器要求您使用或赋值操作的结果。 ++ count 表示,“首先”使 count 增加1,“然后”返回 count 的赋值结果。
在这种情况下,将+1分配给 count 的值作为表达式的值返回。如前所述,在VB中赋值不会产生结果。
因此,在VB中实现这些运算符会带来一些严重的问题。

4
以下扩展方法复制了++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

3
VB.net 中的新宠物恶心之物。感谢 @AdapSpeight 今天给我带来的笑声! - JJS

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接