С# Несогласованные результаты с использованием ключевого слова params - программирование

С# Несогласованные результаты с использованием ключевого слова params

Учитывая следующий метод:

static void ChangeArray(params string[] array) {

    for (int i = 0; i < array.Length; i++) 
        array[i] = array[i] + "s";
}

Это работает, если я назову его передачей массива строк:

string[] array = {"Michael", "Jordan"} // will become {"Michaels", "Jordans"}
ChangeArray(array);

Но не будет работать, если я вызову его с помощью строковых аргументов:

string Michael = "Michael";
string Jordan = "Jordan";
ChangeArray(Michael, Jordan); // This will NOT change the values of the variables

Я понимаю, что компилятор перенесет Майкла и Джордана на массив, так что не должны ли результаты в обоих случаях одинаковыми?

4b9b3361

Ответ 1

Ваш второй пример по существу:

string Michael = "Michael";
string Jordan = "Jordan";
{
    var tmp = new string[] {Michael, Jordan};
    ChangeArray(tmp);
}

так; Фактически значения внутри tmp были изменены... но tmp был отброшен впоследствии, поэтому вы ничего не видите. params не эмулирует ref - он не будет обновлять положени в исходных переменных. Или в коде это не следующее:

string Michael = "Michael";
string Jordan = "Jordan";
{
    var tmp = new string[] {Michael, Jordan};
    ChangeArray(tmp);
    Michael = tmp[0];
    Jordan = tmp[1];
}

Если вам нужно, чтобы он вел себя так, то закодируйте его так - или используйте вместо этого перегрузку, которая принимает параметры ref.

Ответ 2

Причина в том, что string является неизменяемым типом - вы передаете экземпляры string, которые обертываются в массив. Теперь массив содержит две новые строки (с теми же значениями, что и исходные, но разные экземпляры). Когда вы меняете массив, эти копии отбрасываются, и в слоте массива будет содержаться новая строка. Когда ваша функция вернется, временный массив будет выброшен. Таким образом, ваши исходные строки ввода никогда не изменяются (они не могут быть в любом случае, поскольку string - снова - неизменяемый).

Изменить. Я сделал редактирование этого ответа, следуя аргументу Ли в комментариях (я оставлю ответ, как просто для завершения следующего обсуждения). Неизбежная часть действительно не имеет отношения к проблеме. Основная основная проблема заключается в том, что внесены изменения в временный массив, который был выброшен.

Ответ 3

Это странно (я этого не знал), но как указано.

Массив параметров позволяет указать аргументы одним из двух способов при вызове метода:

Аргумент, заданный для массива параметров, может быть единственным выражением типа, который неявно конвертируется (раздел 6.1) в тип массива параметров. В этом случае массив параметров действует точно так же, как параметр значения.

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