C # Передача массива по ссылке - PullRequest
0 голосов
/ 05 февраля 2019

Я знаю, что есть очень похожие вопросы, но мне нужно знать, что происходит в этом конкретном случае.Я написал функцию для обращения элементов многомерного массива по определенному измерению.Для этого я преобразую многомерный массив в зубчатый массив, а затем рекурсивно нахожу измерение массива, в котором выполняется обращение.

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;
}

Теперь моя проблема в том, что при запуске этого метода мой входной массив не был изменен.Разве массив не должен передаваться по ссылке?Когда я присваиваю array = jag, почему он правильно назначен внутри метода, но не снаружи?

Например:

// 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));

Вывод {{00, 01, 02}, {10, 11, 12}, {20, 21, 22}}, который является точно исходным массивом.Если я проверяю вывод в методе Reverse

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

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

, это показывает правильный обращенный массив {{20, 21, 22}, {10, 11, 12}, {00, 01, 02}}.

Разве массив не должен передаваться по ссылке?Почему после локального присваивания мой входной массив ссылается на указатель оригинала, а не на присвоенный?Должен ли я использовать ref ключевое слово для аргумента массива?Если да, можно ли продолжать использовать этот метод как расширение типа Array?

1 Ответ

0 голосов
/ 05 февраля 2019

Все ссылки / значения в параметрах функции, отличные от out и ref , могут рассматриваться как исключительно локальные переменные (хотя вы все равно можете изменитьзначения внутри ссылочных объектов).

В C # мы используем такие методы расширения, как это, поэтому похоже, что это метод расширения без сохранения состояния:

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(...);
...