0

I know there are very similar questions but I need to know what's going on in this specific case. I wrote a function to reverse items of a multidimensional array along a specific dimension. To do this I convert the multidimensional array to a jagged array and than recursively find the array dimension where perform the reversal.

public static void Reverse(this Array array, int dimension, int start, int end)
{
    object[] jag = array.ToJaggedArray();

    if (!jag.ReverseAux(0, dimension, start, end))
        throw new ArgumentOutOfRangeException("dimension", dimension, "Dimension must be nonnegative and less than array dimensions number.");

    array = jag;
}

Now my problem is that when I run this method my input array has not been modified. Shouldn't an array be passed by reference? When I assign array = jag why it is correctly assigned inside the method but not outside?

For example:

// create 2D array of strings
string[,] ar = {{"00", "01", "02"},
                {"10", "11", "12"},
                {"20", "21", "22"}};
// reverse the first dimension (rows)
ar.Reverse(0, 0, 2);
// show the result
MessageBox.Show(ar.ToString(null, null));

The output is {{00, 01, 02}, {10, 11, 12}, {20, 21, 22}} that is exactly the original array. If I check the output in Reverse method

public static void Reverse(this Array array, int dimension, int start, int end)
{
    //...

    array = jag;
    System.Windows.Forms.MessageBox.Show(array.ToString(null, null));
}

this shows the correct reversed array {{20, 21, 22}, {10, 11, 12}, {00, 01, 02}}.

Shouldn't an array be passed by reference? Why after the local assignment my input array is referencing the orignal pointer and not the assigned? Should I use ref keyword for array argument? If yes is it possible to continue using this method as an extension of Array type?

5
  • Parameters are passed by value unless you use the ref or out modifiers. Extension methods don't support passing by reference however. Commented Feb 5, 2019 at 12:27
  • @Lee - There is also in modiier to pass by reference added in 7.3 Commented Feb 5, 2019 at 12:29
  • @Shoter that won't help here neither. Commented Feb 5, 2019 at 12:31
  • The confusion here is because C# hides pointers from the users, unless you explicitly tell so, every param is passed by value. An array is a continuous amount of memory, the parameter that you receive is actually the pointer to where that memory starts. Updates to the array items (array[x]) are reflected to the user, but the updates to the pointer (array variable itself) are not. Commented Feb 5, 2019 at 12:38
  • Possible duplicate of Are arrays or lists passed by default by reference in c#? Commented Feb 5, 2019 at 12:57

1 Answer 1

3

All references/values in paramaters of function other than with out and ref modifiers can be considered as solely local variables (though, you still can change values inside referenced objects).

In C# we do such extension methods like this, so it looks like it is stateless extension method:

public static Array Reverse(this Array array, int dimension, int start, int end)
{
    object[] jag = array.ToJaggedArray();

    if (!jag.ReverseAux(0, dimension, start, end))
        throw new ArgumentOutOfRangeException("dimension", dimension, "Dimension must be nonnegative and less than array dimensions number.");

    return jag;
}

var output = input.Reverse(...);
Sign up to request clarification or add additional context in comments.

Comments

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.