Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# Pass by Reference (ref keyword) Issue

Tags:

c++

c#

reference

I'm having trouble understanding what exactly the ref keyword in C# does. In my C++ code I am creating a string variable along with a pointer and reference variable pointing to it. I'm passing it to either a Delete or Change function, and as expected all 3 variables are being modified.

However, with C#, I'm creating variable x and initialising it with string data. I'm creating a variable y which should under the hood be a reference to x. I'm then passing x into the Change or Delete method with a ref keyword, causing the variable inside the method, as well as x to be modified. However, y is not modified, even though it should be a reference to x, just like in C++. This is not just an issue with strings either, as I have tried the above test with a C# object, and had the same results.

Does this mean y copied x by value when I executed var y = x?

C++

#include <iostream>
using namespace std;

void Delete(string &variable)
{
    variable = "";
}

void Change(string &variable)
{
    variable = "changed data";
}

void main()
{
    string x = "data";
    string *y = &x;
    string &z = x;
    Delete(x);
}

c#

namespace ConsoleApplication1
{
    public class Program
    {
        public static void Main(string[] args)
        {
            var x = "data";
            var y = x;
            Change(ref x);
        }


        public static void Delete(ref string variable)
        {
            variable = null;
        }

        public static void Change(ref string variable)
        {
            variable = "changed";
        }
    }
}
like image 527
Sharpiro Avatar asked Sep 10 '26 15:09

Sharpiro


2 Answers

This line: var y = x; makes y a copy of x and not a reference to x in c# so it was not suppose to change when you called Changed function.

There doesn't appear to be an easy way to reproduce the same C++ behavior in C# (or most other languages).

When you pass a non value type object as an argument to a function, the object is passed by value but the object content (properties/fields,etc..) are passed by reference(you can change them from inside the function), when you pass the object with the "ref" keyword, the object itself is byref and can also be changed, (its the same as sending a pointer vs sending a double pointer to a struct (wich itself holds pointers) in c++/c).

like image 114
Dr.Haimovitz Avatar answered Sep 12 '26 05:09

Dr.Haimovitz


There is no way, other than 'unsafe' code, to reproduce this behavior in C#. The C++ ability to have a pointer remain fixed to another variable, even when the second variable's identity changes, is simply not available in most other languages.

This is not a special feature of strings or any other type. For example, at the end of the following C++ code, 'g' points to the updated 'f', which is set to 'SomeOtherFoo':

Foo f;
Foo *g = &f;
f = SomeOtherFoo();
//'g' points to the updated 'f'

In 'safe' C#, at the end of the following code, 'g' is still the original object, not the new one returned by 'SomeOtherFoo':

Foo f = new Foo();
Foo g = f;
f = SomeOtherFoo();
//'g' does not point to the updated 'f'
like image 35
Dave Doknjas Avatar answered Sep 12 '26 06:09

Dave Doknjas