-2

I needed to verify this in linqpad but this code evaluates to 0 the first time. Why does this occur in C#?

var integer = 0;
while(true){
    var @string = integer++.ToString();
    Console.WriteLine(@string);
}

I also verified that evaluates to 1 first.

var integer = 0;
while(true){
    var @string = (++integer).ToString();
    Console.WriteLine(@string);
}

I get the difference between ++x and x++. just was expecting it to do x++ and then the ToString() gets called.

onewaytofindout
  • 167
  • 1
  • 11
  • 1
    Has nothing to do with ToString(). Consult a decent C# tutorial or reference before asking here. – H H Jul 05 '16 at 18:45
  • have a look here to see if it helps: http://stackoverflow.com/questions/3346450/what-is-the-difference-between-i-and-i – sous2817 Jul 05 '16 at 18:47
  • 3
    You mean "why does this code operate correctly in c#"? Please clarify what you expected and why you expected it. – Lasse V. Karlsen Jul 05 '16 at 18:50
  • I expected this to occur. integer = 0; integer++ //integer now is 1; integer.ToString(); //evaluates to a 1. – onewaytofindout Jul 05 '16 at 19:41
  • I'm not sure why this question is getting downvoted. He is not asking for the difference between post and pre increment. He is asking for an explanation for what appears to be unexpected behavior, namely, that he expected the `ToString` method to be called after `i` was incremented. – Chris Dunaway Jul 05 '16 at 20:58
  • 1
    That is not unexpected behavior. It is another good reason to avoid `++` in expressions. – H H Jul 05 '16 at 21:05
  • @ChrisDunaway `that he expected the ToString method to be called after i was incremented` It *is* called after `i` is incremented. To claim that it's not is to not understand what the pre/post increment operators do. – Servy Jul 06 '16 at 20:34
  • @Servy - But the `ToString` method does not operate on the incremented value of `integer`. It operates on the previous value of `integer`. That's what I meant. – Chris Dunaway Jul 06 '16 at 21:03
  • 1
    @ChrisDunaway It operates on the value that the `++` operator evaluates to, as is defined by its specs. The code would be the same if you didn't call `ToString` and just held the integer result in a variable. At the end of the day the question is fundamentally asking what the `++` operators do; it asserts that it understands them and then immediately follows it by asking what they do. – Servy Jul 06 '16 at 21:06
  • @Servy - I get what you're saying, but when I look at the IL of a simple example (see my answer), unless I am reading it wrong, the value of `i` gets incremented (via the `add` instruction) _before_ the call to `ToString` which operates on a copy of `i`. – Chris Dunaway Jul 06 '16 at 21:17
  • @ChrisDunaway Yes, the variable is incremented before `ToString` is called. That's what I specifically said in response to you asserting the opposite. – Servy Jul 06 '16 at 21:19

4 Answers4

1

My understanding of the post increment operator is that it first saves the value of the variable (i in this case), increments i and then uses the saved value (in this example, in the call to ToString()).

This code:

int i = 5;
string s = i++.ToString();

is equivalent to:

int i = 5;
int temp = i;
i = i + 1;
var s = temp.ToString();

You can use LinqPad or other tool (ILSpy, etc.) to look at the IL:

IL_0000:  nop         
IL_0001:  ldc.i4.5    
IL_0002:  stloc.0     // i
IL_0003:  ldloc.0     // i
IL_0004:  dup         
IL_0005:  ldc.i4.1    
IL_0006:  add         
IL_0007:  stloc.0     // i
IL_0008:  stloc.2     // CS$0$0000
IL_0009:  ldloca.s    02 // CS$0$0000
IL_000B:  call        System.Int32.ToString
IL_0010:  stloc.1     // s
IL_0011:  ret         

Here's a blog post by Eric Lippert with more information

Chris Dunaway
  • 10,974
  • 4
  • 36
  • 48
  • An explanation for the downvote would be appreciated. – Chris Dunaway Jul 06 '16 at 21:09
  • If you read your own linked article you'd see that your representation of the order of the operations is wrong. In fact, it's specifically called out by Eric as being the incorrect way to think of it. – Servy Jul 06 '16 at 21:14
  • @Servy - Does my edit more accurately reflect how it works? I'd appreciate the feedback. – Chris Dunaway Jul 06 '16 at 21:34
  • Your text description of what is happening also needs to be updated. – Servy Jul 06 '16 at 21:35
  • The description is correct for a post increment, but not a pre increment, and yet you claim that it applies to both. – Servy Jul 07 '16 at 13:10
1

Fundamentally, the behavior of the ++ operator in i++.ToString() is no different from its behavior when calling any other function that takes i as a parameter. For example, you would fully expect the original value of i to be passed if you called SomeFunction(i++).

Consider, for example, an extension method:

public static class GoofyExtensions
{
    public static string Frob(this int x)
    {
        return x.ToString();
    }
}

Now, that can be called as if it were an instance method:

var s = i++.Frob();

The compiler turns that into a call to the static Frob method:

var s = GoofyExtensions.Frob(i++);

It would be pretty surprising to find that i++.Frob() returned a different value than i++.ToString().

The point here is that although ToString() is a method without parameters, internally all instance methods have an implicit parameter: the instance. If you examine the generated MSIL, you'll see that a reference to the instance is passed as a parameter to all instance methods. So i.ToString() is in a very real sense a call to Int32.ToString(i).

Jim Mischel
  • 131,090
  • 20
  • 188
  • 351
0

https://msdn.microsoft.com/en-us/library/6a71f45d.aspx

The postfix version of ++ returns the value of the integer and then increments, whereas the prefix version of ++ increments then returns. So in both cases you're calling ToString on the returned value, but the positioning of the operator is what determines which value is being returned.

  • i get the difference between ++x and x++. just was expecting it to do x++ and then the ToString() gets called. – onewaytofindout Jul 05 '16 at 19:43
  • To elaborate on Matt's additional comments, the call to `integer++` returns an Integer object which is separate from the one stored in memory. The behavior you were expecting was probably more like `integer++; integer.ToString();` – Lee Painton Jul 07 '16 at 00:41
  • As an interesting example, in the following code: `int i=0; int j=i++; int k=j++;` The value of k winds up being 0. – Lee Painton Jul 07 '16 at 00:50
0

Both of these operators, postfix and prefix, act as functions. They return a value after performing an operation on their parameter, in this case integer. It is unconventional looking, but that's what it is doing.

So essentially, you're doing:

var @string = postfixplusplus(integer).ToString();

I hope this way of thinking explains a little bit.

matt.condit
  • 121
  • 1
  • 1
  • 15