2

I have been wondering, why isn't my method, modifying the array, when I used it as a parameter and made it equal to another array with different values, inside the method? Am I just changing the reference address?

    static void Main()
    {
        string[] array = { "yes", "no", "maybe" };
        TestO(array); // Still "yes", "no", "maybe"
    }

    static void TestO(string[] array)
    {
        string[] secondArray = new string[array.Length]; 
        secondArray[0] = "1";
        secondArray[1] = "2";
        secondArray[2] = "3";
        array = secondArray; 
    }

My guess: I did not modify the array inside the Main(), because when doing array = secondArray; in the Test0() method, I just changed the reference address of array to secondArray.

If my guess is not right, my question is, why exactly is it not getting modified?

(I know that I can just modify Test0() to a string[] return method and return the modified secondArray and pass it on to the array in Main())

Another questions is: If I use the string[] return method, and declare the following:

        static void Main()
    {
        string[] array = { "yes", "no", "maybe" };
        array = TestO(array); 
    }

    static string[] TestO(string[] methodArray)
    {
        string[] secondArray = new string[methodArray.Length];
        secondArray[0] = "1";
        secondArray[1] = "2";
        secondArray[2] = "3";
        return secondArray; 
    }

array = TestO(array); am I just passing the reference address of the secondArray[] to array[] or am I passing only the values of it? (Most probably it will be the reference address, but I wanted to be sure if mistaken)

2
  • 1
    For the first question - array is a reference type and so when the function Test0 is called it calls a copy constructor of the array's reference so basically you assign the modified array to local copy of the reference, thus not affecting it outside the function scope. Commented Feb 20, 2022 at 17:46
  • 1
    For the second question - because secondArray is a reference type - the reference is passed, not the values themselves Commented Feb 20, 2022 at 17:48

3 Answers 3

3

I just changed the reference address of array to secondArray. If my guess is not right, my question is, why exactly is it not getting modified?

I think you're leaning towards appreciating that there are two references to one data in memory (there are not two data); you have a variable array that points to data. You call a method and another, copy reference is established to the same data. You made a new object, then you pointed the copied reference at the new object, leaving the original reference pointing to the original data, then you threw the copy reference and the new data away.. You're back to the exact same situation you started with.

Pictorially, line by line, it might look like (I renamed your method argument to arrayX so the difference is obvious):

enter image description here

If you decorate the argument with ref and call it with ref there is no copy, so the called method can modify the original reference and point it somewhere else:

enter image description here

Note that in either of these cases it's perfectly possible to modify the contents of the array. Doing:

arrayX[0] = "New data";

..would take effect in either case and printing array[0] would show "New data". When modifying the data at the end of the arrow it matters not whether the starting point is an original reference or a copy. This is purely about whether the method has the power to point the original reference passed to it, to a different object or not

Generally we don't do it. We adopt the style of your second code block - to return the data. It may help to see it as rude - imagine your friend says he'll look after your plant while you're on holiday; you give your keys to your friend. He swaps your plant for a different one that he likes better; you're upset because you had that plant for ten years..

There are very few reasons to use ref, or the related "power to overwite your reference" - out. Don't use it for "I wanted to return multiple things from my method" - in an OO world we can always return one thing that represents two items of data. We don't need to "return two things"; we can return one thing with two things inside it...

//don't:
void GetPerson(ref string name, ref int age)

//consider a class:
Person GetPerson()
  return new Person(){ Name = ..., Age = ...}

//or a Tuple
(string Name, int Age) GetPerson

Let the calling method choose whether its own variable should be overwritten, rather than having some "third party" pull that rug from under its feet

Sign up to request clarification or add additional context in comments.

Comments

3

When you pass an array to a method

static void Test0(string[] array)
{

You are passing a reference to that array. That reference is effectively immutable (you're getting a copy of the reference, not the original one), so you can't change the parameter reference and expect it to affect the code outside of the Test method.

While you can do this to get the behavior you want:

static void Test0(ref string[] array)
{

it's not considered good C# style. Strings are themselves immutable; the "correct" style is to return them from the method. This is also true of string arrays.

The only thing you would be saving by using this technique is an extra reference and a return statement, since you're still creating new strings and a new array anyway.

Comments

2

you don't need to return anything , just use a ref

static void Test( ref string[] array)
    {
        string[] secondArray = new string[array.Length]; 
        secondArray[0] = "1";
        secondArray[1] = "2";
        secondArray[2] = "3";
        array = secondArray; 
    }

14 Comments

Nooo.... Don't encourage it.
@CaiusJard ok you are right, I don' t want to make waves here any more. People are too serious here, don' t appreciate any joke
Mmm.. I personally feel you cannot joke with someone's education.. Not wishing to come across as overly serious, but the general ambience in SO is intended to err more towards professional than joking
I completely agree, and I'm definitely not saying "there is only one right answer", but it's vital that answers wishing to convey that aren't just "here's a fish you wanted" but instead "here's fish A and I caught it like.. becuase... And also here is fish B which will also meet your needs because ... and I caught it like ...". Had your answer included more words of explanation than code I would have been much less likely to speak up and say "hang on"..
There are different kinds of questions here, but lets divvy them broadly into newbies looking for help with really basic stuff that's hard to google, an dmore experienced sorts looking for really precise, targeted advice for a highly specific problem that only a few SME would be able to answer well. It's actually the latter questions where you can get away with a code-only with minimal explanation, because the ability to understand the entire context, the whys and wherefores is already there in the OP.In the really basic questions;they are the people who benefit most from extra explanation
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.