views:

386

answers:

5

Hi

I am trying a simple Extension Method example and am unable to increment or decrement an int. Here is the code

static class ExtensionMethodsExp
{
    public static void Print(this object o)
    {
        Console.WriteLine("This is print: {0}", o.ToString());
    }

    public static int Double(this int i)
    {
        return i * 2;
    }
    public static int Decrement(this int i)
    {
         return i--;
    }

    public static int Increment(this int i)
    {
        return i++;

    }
}

}

Program Code is

class Program
{
    static void Main(string[] args)
    {

       int myNumber = 10;
       myNumber.Print();

       myNumber = myNumber.Double();
       myNumber.Print();

       myNumber = myNumber.Decrement(); 
       myNumber.Print();

       myNumber = myNumber.Increment();
       myNumber.Print();

       myNumber.Increment().Double().Print();
       Console.ReadKey();
    }
}

I am getting following as output

This is print: 10

This is print: 20

This is print: 20

This is print: 20

This is print: 40

Any idea why Decrement or Increment should not work here. Is there something I am missing? thanks

+9  A: 

Try this:

public static int Decrement(this int i)
{
     return --i;
}

public static int Increment(this int i)
{
    return ++i;
}
Gerardo Contijoch
This worked cool, thanks. But why didn't i-- or i++ work?
MvsW
I think i+1 and i-1 would be clearer - there is no need to increment the input value, since it isn't used again.
Marc Gravell
@MvsW: i-- and i++ do not work because it is the post-increment/decrement oprator so order is "first take value then increment/decrement it" while --i/++i is "first increment/decrement value then take it". But i+1/i-1 would be much cleaner because eith i--/i++ you change the value stored in i but do not use it instead of returning it.
rstevens
+5  A: 

The reason your code is not working is because of the way you are using the Increment and Decrement operators.

When you write:

return i++;

The value of i is returned BEFORE the increment occurs.

Try this:

return ++i;

or better yet, this:

return i + 1;
Robert Harvey
+3  A: 

It's not a matter of reference, since you are assigning the return value back to the value.

The issue here is that i++ increments after it is used. In this case, it is being returned, and then incremented. Since the variable is a value type, it's only the local variable inside Increment() that is being incremented.

If you use ++i then the local member is incremented and then returned, which is more what you were expecting.

Having said that, it is confusing to name your method Increment or Decrement since it does not automatically assign the value back to the original. Have you tried passing in ref this i? I have no idea if ref can be used in this situation, but it may make the method naming more accurate. Eric Lippert has thwarted this idea.

Richard Szalay
You can't make an extension method on a ref. What would it look like at the call site? (ref x).Foo(y) ? That would be goofy, so we don't allow it.
Eric Lippert
Good point. I was thinking more from the compiled form, since it's a static call.
Richard Szalay
A: 

This is because i++ doesn't increment the number until after the function has been completely evaluated. Unfortunately, in your example, you return the original value and the incremented value is lost on the stack!

++i increments i before the function evaluates.

James L
A: 

++i means:

  • Increment the value of i
  • Return the incremented value

i++ means:

  • Remember the current value of i
  • Increment the value of i
  • Remember the previous value of i (i.e. from before you incremented it)

The one is called the "preincrement" operator, and the other is called the "postincrement" operator.

ChrisW