C# /. NET имеет переменные параметры функции, передавая Array
тип ссылки (в отличие от C/C++, который просто помещает все значения непосредственно в стек, для лучшего и худшего).Будет ли `params` в C# всегда вызывать новый массив для каждого вызова?
В C# мире это имеет опрятное преимущество, что позволяет вам вызывать ту же функцию, либо с «сырыми» аргументами или многоразовым экземпляром массива:
CultureInfo c = CultureInfo.InvariantCulture;
String formatted0 = String.Format(c, "{0} {1} {2}", 1, 2, 3);
Int32 third = 3;
String formatted0 = String.Format(c, "{0} {1} {2}", 1, 2, third);
Object[] values = new Object[] { 1, 2, 3 };
String formatted1 = String.Format(c, "{0} {1} {2}", values);
Это означает, что сгенерированный CIL эквивалентен:
String formatted0 = String.Format(c, "{0} {1} {2}", new Object[] { 1, 2, 3 });
Int32 third = 3;
String formatted0 = String.Format(c, "{0} {1} {2}", new Object[] { 1, 2, third });
Object[] values = new Object[] { 1, 2, 3 };
String formatted1 = String.Format(c, "{0} {1} {2}", values);
Это означает, что (в не-оптимизирующий JIT компилятор) каждый вызов будет выделить новый Object[]
экземпляр - хотя в третьем примере вы сможете хранить массив как поле или другое многоразовое значение, чтобы устранить новое распределение по каждые по телефону String.Format
.
Но в официальной среде CLR и JIT есть какие-либо оптимизации для устранения этого распределения? Или, может быть, массив помечен специально, чтобы он был освобожден, как только выполнение покинет область вызова?
Возможно, потому, что компилятор C# или JIT знает количество аргументов (при использовании «raw») может ли он сделать то же самое, что и ключевое слово stackalloc
, и поместить массив в стек и, следовательно, не нужно освобождать Это?
re не интернирование: большое дело! Если метод изменяет массив, не зная, откуда он произошел, и что с ним будет потом, и ожидает, что это будет нормально, он заслуживает того, что получает. – jmoreno