С# Несогласованные результаты с использованием ключевого слова 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
Я понимаю, что компилятор перенесет Майкла и Джордана на массив, так что не должны ли результаты в обоих случаях одинаковыми?
Ответы
Ответ 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) в тип элемента массива параметров. В этом случае вызов создает экземпляр типа массива параметров с длиной, соответствующей количеству аргументов, инициализирует элементы экземпляра массива с заданными значениями аргументов и использует только что созданный экземпляр массива в качестве фактического аргумента.