0

I have something interesting that I want to understand little deeper.

I have an extension class that extends int:

public static class MyExtension
    {
        public static void GetProp(this int i, MyObject o)
        {
            var val = i;
            o.sum = i;
        }
    }

That uses a class as one of its parameter:

public class MyObject
    {
        public int sum { get; set; }
    }

Now, lets see the unit test class:

    [TestClass]
    public class UnitTest1
    {
        [TestMethod]
        public void test()
        {
            int a = 1;
            int b = 2;
            int sum = 0;
            Add(a, b, sum);

//Here, sum=3 but after its execution, sum looses its value and retains the value sum = 0

            int test = 4;
            MyObject obj = new MyObject();
            test.GetProp(obj);

But in the above code when I pass the variable using the extension method, the obj.sum retains its value obj.sum = 4 . I am not passing any value by reference. The first portion of code seems to follow the passing ByVal. But the second portion of extension method, the value is retained as if its passed as ByRef

            string s = sum.ToString();
            string p = obj.sum.ToString();
        }

        private void Add(int x, int y, int sum)
        {
            sum = x + y;
        }
    }

Can someone explain the mechanism behind this. Thanks

Satyajit
  • 1,971
  • 5
  • 28
  • 51
  • are you familiar with how to use the `ref` key word within an extension method http://stackoverflow.com/questions/2618597/impossible-to-use-ref-and-out-for-first-this-parameter-in-extension-methods – MethodMan Jul 31 '15 at 17:24

3 Answers3

3

All parameters are send by value, unless you specify them with the ref or out keyword. Passing a parameter by value means that the value is copied.

However, when you pass an object by value it's not the object that is copied, it's the reference that is copied. That means that you have two references to the same object, one in the obj variable and one in the o parameter, but only one object.

When the extension method accessed the object, it's the same object as outside the method. Any change to the property made using the o parameter will be visible when you later access it using the obj variable.

Guffa
  • 687,336
  • 108
  • 737
  • 1,005
2

This is the difference between passing by reference and passing a reference object (class). In GetProp, you aren't modifying the reference obj, you are modifying the MyObject instance that is referred by obj.

Daniel A. White
  • 187,200
  • 47
  • 362
  • 445
0

If I understand your question, you're confused about why the sum variable isn't changed when it is passed by value, but the obj.sum property does retain its value when obj is passed by reference. The other answers do a good job of explaining this.

In your question, you pass a parameter by value as a receiver, and this confuses your question a bit. Your question appears to be, "why is it that when I pass normally, it's treated as by-value, but when I pass as a receiver to an extension method, it's by-reference?"

Ah. Try assigning a new value to the receiver and see what happens at the call site:

    public static void GetProp(this int i, MyObject o)
    {
        o.sum = i;
        i = 5000;
    }

You'll find that the variable test at the call site is not affected by this, since the receiver is also passed by value!

CSJ
  • 3,641
  • 2
  • 19
  • 29