Предлагаю рассмотреть следующий код:
public void M1() {
var array = new int[10];
for (int i = 0; i < array.Length; i++)
array[i] = 1;
}
public void M2() {
var array = new int[10];
int len = 10; // array.Length;
for (int i = 0; i < len; i++)
array[i] = 1;
}
public void M3() {
var array = new int[10];
int len = 20;
for (int i = 0; i < len; i++)
array[i] = 1;
}
public void M4(int len) {
var array = new int[10];
for (int i = 0; i < len; i++)
array[i] = 1;
}
Смотрим машинный код на sharplab.io (вкладка JIT Asm).
Можно увидеть, что в методе M1
код ассемблера не содержит проверок на выход за пределы массива.
В методе M2
компилятор достаточно умён, чтобы определить, что значение переменной len
равно размеру массива (можно задать явно 10
, можно задать array.Length
) и тоже не вставляет такие проверки.
В методе M3
значение len
отличается от константы, используемой при создании массива, поэтому генерируется дополнительный код с проверками.
В методе M4
аналогично, компилятор не может знать, какое значение придёт извне в параметр len
, поэтому добавляет кучу проверок.
Примечание.
При использовании ArrayPool<T>
в большинстве случаев не получится использовать свойство Length
, т. к. размер массива, полученного из пула, будет превышать запрошенный размер. Поэтому придётся указывать размер переменной/константой.