Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Passing Objects By Reference or Value in C#

In C#, I have always thought that non-primitive variables were passed by reference and primitive values passed by value.

So when passing to a method any non-primitive object, anything done to the object in the method would effect the object being passed. (C# 101 stuff)

However, I have noticed that when I pass a System.Drawing.Image object, that this does not seem to be the case? If I pass a system.drawing.image object to another method, and load an image onto that object, then let that method go out of scope and go back to the calling method, that image is not loaded on the original object?

Why is this?

like image 663
Michael Avatar asked Oct 09 '22 00:10

Michael


People also ask

Are objects passed by reference in C?

There are references in C, it's just not an official language term like it is in C++. "reference" is a widely used programming term that long predates the C++ standardizing of it. Passing a pointer to an object is passing that object by reference.

Are objects passed by value or reference?

Object references are passed by value The reason is that Java object variables are simply references that point to real objects in the memory heap. Therefore, even though Java passes parameters to methods by value, if the variable points to an object reference, the real object will also be changed.

Does C use pass by value or reference?

C always uses 'pass by value' to pass arguments to functions (another term is 'call by value', which means the same thing), which means the code within a function cannot alter the arguments used to call the function, even if the values are changed inside the function.

What is the difference between pass by value and pass by reference in C?

The main difference between pass by value and pass by reference is that, in a pass by value, the parameter value copies to another variable while, in a pass by reference, the actual parameter passes to the function. A computer program is a set of instructions that directs the CPU to perform a certain task.


1 Answers

Objects aren't passed at all. By default, the argument is evaluated and its value is passed, by value, as the initial value of the parameter of the method you're calling. Now the important point is that the value is a reference for reference types - a way of getting to an object (or null). Changes to that object will be visible from the caller. However, changing the value of the parameter to refer to a different object will not be visible when you're using pass by value, which is the default for all types.

If you want to use pass-by-reference, you must use out or ref, whether the parameter type is a value type or a reference type. In that case, effectively the variable itself is passed by reference, so the parameter uses the same storage location as the argument - and changes to the parameter itself are seen by the caller.

So:

public void Foo(Image image)
{
    // This change won't be seen by the caller: it's changing the value
    // of the parameter.
    image = Image.FromStream(...);
}

public void Foo(ref Image image)
{
    // This change *will* be seen by the caller: it's changing the value
    // of the parameter, but we're using pass by reference
    image = Image.FromStream(...);
}

public void Foo(Image image)
{
    // This change *will* be seen by the caller: it's changing the data
    // within the object that the parameter value refers to.
    image.RotateFlip(...);
}

I have an article which goes into a lot more detail in this. Basically, "pass by reference" doesn't mean what you think it means.

like image 635
Jon Skeet Avatar answered Oct 18 '22 20:10

Jon Skeet