开发者

No increment operator in VB.net

I am fairly new to vb.net and came across this issue while converting a for loop in C# to VB.net I realized that the increment operators are not available in vb.net (++ and --) whereas i was able it do something like cnt +=1

I researched a bit and came across Eric's post on the same, but wasn't really able to understand fully on it. He mentions of In VB, a STATEMENT cannot be just an EXPRESSION. not sure how that really fits in.

I hope someone here would be able to explain why this doesn't work in the same w开发者_JAVA百科ay as it does in C#. (Hope this will also hold true as in why we have == in C# for comparison)


I would say that the language designers simply thought that BASIC was a better baseline than C, when designing Visual BASIC. You can follow the lineage of C (and, earlier, BCPL) through C++, Java and C#.

The VB lineage comes from the original BASIC from Dartmouth (and, earlier, Fortran) and is a different beast altogether.

In other words, what started as the venerable BASIC:

LET I = I + 1

has probably been hacked and destroyed enough :-)

As per Eric's post, i++; is indeed just an expression, one that yields i with the side effect that i is incremented after the event (similar to the non-side-effect expression i;).

That's because C allows these naked expressions, even things like 42; which doesn't really do much but is perfectly valid. In other words, the following is a complete C program:

int main (void) { 1; 2; 3; 4; 5; 6; 7; 8; 9; return 0; }

All those expressions are valid but useless (except the 0 at the end of course).

In BASIC, this was not really done, because BASIC consisted of statements (things that did something). That's why i += 1 (a statement incrementing i) is considered okay, but i++ (an expression doing nothing which just happens to have a side effect which increments i) isn't. You could argue that it's just semantic hair-splitting but that's just the way it is.

You should be thankful for small mercies, at least you're not having to deal with COBOL:

ADD 1 TO DD_WS_I.


Simply because the designers thought that i++ is unnecessary when you have i += 1.

For loops don't need either one, so you don't lose anything.

It's Visual Basic after all... why make it complicated?


As @paxdiablo said, in VB (or rather, in its ancestor BASIC), everything used to be a statement. And in fact, every statement was introduced by a keyword.

So to assign a variable we had

LET x = x + 1

and to call a method, we had

CALL SomeMethod

In VB, the LET and CALL were finally dropped (except in one special circumstance) because it’s completely redundant and doesn’t add clarity. But the underlying lexical grammar of VB didn’t change all that much: each statement still has to be a statement. i++ isn’t a statement in VB, since it lacks either a function call or an assignment.

There was an argument in the first version of VB.NET whether to introduce pre- and post-increment operators like in C#. It was decided not to do this, for a fairly simple reason: using side-effects in expressions isn’t recommended anyway. It usually lets clarity suffer. So even in C# legitimate uses of i++ in an expression are very rare, and legitimate uses of ++i are rarer still (though I won’t deny that in some cases it adds clarity).

In most cases you can use i += 1 just fine and this perfectly well expresses the intent.

Notice that in C++, the situation is fundamentally different because here (but not in C#!) i++ actually has a different semantic than i += 1 due to operator overloading (in C# we also have operator overloading but ++ cannot be overloaded).


As an example of the difference between expression and statement in VB, in VB the following generates a compiler error since count += 1 increments count by 1, but the whole expression count += 1 does not return a result, so it can't be used as a parameter.

Dim count As Integer = 0
Console.WriteLine(count += 1)  ' compiler error

You have to do this instead

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

Of course same applies to using the += operator on a String.

What does "In VB, a statement cannot just be an expression" mean?

  • The VB compiler requires results to be consumed in some assignment or other operation.
  • Because of this an assignment operation in VB does not produce a result. If it did the VB compiler would not allow it to stand alone as a statement (the compiler requires results be consumed).
  • Thus assignments in VB can be used as statements, but not as expressions. That is you cannot use an assignment statement as a parameter to a method, or as an intermediate result.
  • In C# an assignment operation does produce a value. Thus in order for assignments to stand alone as statements, the compiler does not require all results to be consumed.
  • The corollary in C# is that any other operation that produces a result can stand alone as a statement. 2 + 2 for instance produces the result 4 and can stand alone as a statement, whereas in VB it can't.

Simplified answer to "Why are pre and post increment operators not available in VB?"

count++ says, first return the value of count, then increment count (and do not return the value of the assignment to count).
In this case the incremented value is not used (the value before incrementing is used). As mentioned before, the VB compiler requires you use or assign values of operations.

++count says, first increment count, then return the value of the assignment to count.
In this case, the value of assigning +1 to count is returned as the value of the expression. As mentioned before, assignments in VB do not produce a result.
Thus there would be some serious pain implementing these operators in VB.


The following extension methods replicate ++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
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜