-3

When I passed my object to a function in c# and change its values, the originals instance values are changed? I have been looking into why this happens but no one is explaining.

class Program
{
    static void Main(string[] args)
    {
        Class1 obj = new Class1();
        obj.x = 10;
        test(obj);
        Console.WriteLine(obj.x); // prints 200
    }

    static void test(Class1 a)
    {
        a.x = 200;
    }
}

When I tried this with the int data type, it did not change.

I have a deep understand of pass my value and reference. But in c#, I am quite confused on what is going on?

I want to know why c# changes original obj function value. It should still print 10.

Juansdk
  • 93
  • 5
  • Since you have good understanding of "pass by value vs. pass by reference" it is very hard to suggest more help. You may want to clarify what you expect this code to do so someone can reason about what else you need explanation of. – Alexei Levenkov Feb 22 '21 at 07:29
  • "I have a deep understand of pass my value and reference" Obviously not. In .net are reference-types. Doing something on one reference is thuerefor reflected in **all** references. – MakePeaceGreatAgain Feb 22 '21 at 07:30
  • @HimBromBeere Ok, so by default, custom objects will be passed by refrence? – Juansdk Feb 22 '21 at 07:31
  • 2
    all objects except the primitive types will be passed by reference. Could you please tell us where did you try to research this topic? – Mong Zhu Feb 22 '21 at 07:31
  • @MongZhu Is it possible to change this? – Juansdk Feb 22 '21 at 07:32
  • @Juansdk, what you want to achieve? Actually when u write code u work with variables, and all variables are passed as parameters by value. But for variables, which store reference to an object, it is the same, cause of copy of reference is still a reference to the same object. That's why we say, that reference types are passed by reference. – Ryan Feb 22 '21 at 07:35
  • @Juansdk, actually it's *possible* to "change" that behavior by using struct instead of class. In that case it will be passed by value, and the original copy will not be affected. But be aware that structs will be on stack, not heap, so don't keep big chunk of structs to avoid overflows. – Just Shadow Feb 22 '21 at 07:36
  • 1
    It is not possible to change this behaviour, but what you can do, is make sure your methods do not alter the original object. Instead create local variables within the method to work on, e.g. `int a = x.a;` and then do `x = 200;` or whatever operations you need to do. – Lars Kristensen Feb 22 '21 at 07:36
  • You can create copies of objects, there is even a built-in method [MemberwiseClone](https://learn.microsoft.com/en-us/dotnet/api/system.object.memberwiseclone?view=net-5.0). But this is only a 'shallow copy', properties can be objects as well an these will not be copied (see 'deep copy'), ie. two cloned objects that contain a List-property will point to the same List. – KekuSemau Feb 22 '21 at 07:43

1 Answers1

1

When you tried it with int, a copy of the int variable was passed. For the time you ran the method your memory contained two ints, you modified one which was then thrown away

Had you passed the int with ref the original int would have been passed and the method would have modified the original value

When you pass objects, a reference to the object is passed and whether you use ref or not you can modify properties of the object and the calling method will see those modifications. The difference with using ref or not on an object is that with ref you can swap the object for a whole new one (with new) keyword and the original method will get the new object. Without ref, the original method will retain the original object because the reference that was passed (and subsequently changed for a new object) was a copy

Forget calling a method for a moment, let's do it simpler:

int x = 0;
int y = x;
y++;

What value do you now expect x to have?

It has 0; y is a copy of the value x has


Person p = new Person(){ Name = "John" };
Person q = p;
q.Name = "Mary";

What name do you expect p now to have? (It's Mary)


This is like what is happening with your posted code, so you already understand it in the context of not calling a method - y is a copy of x (and they refer to different data in memory, changing one does not change the other), q is a copy of a reference to p (but they both refer to the same data in memory, changing the data means both references see the change)

Caius Jard
  • 72,509
  • 5
  • 49
  • 80