Когда я делаю присвоение на out
или ref
параметр, является значением, сразу присвоенным ссылке, обеспеченной вызывающей стороной, или out
и ref
значения параметров присвоили ссылкам, когда метод возвращается? Если метод выдает исключение, значения возвращаются?
Например:
int callerOutValue = 1;
int callerRefValue = 1;
MyMethod(123456, out callerOutValue, ref callerRefValue);
bool MyMethod(int inValue, out int outValue, ref int refValue)
{
outValue = 2;
refValue = 2;
throw new ArgumentException();
// Is callerOutValue 1 or 2?
// Is callerRefValue 1 or 2?
}
С
и и из параметров
позволяют методу работать с фактическими ссылками, которые звонят, все изменения в этих ссылках сразу отражаются к абонеру, когда управление возвращается.
Это означает, что в вашем примере выше (если вы собирались поймать ArgumentException
, конечно), ovalue
и Refvalue
будут установлены на 2.
Также важно отметить, что из
и
и
являются идентичными концепциями на уровне IL - это только компилятор C #, который обеспечивает дополнительный правил
Для этого требуется, чтобы способ установить его значение до возвращения. Таким образом, от перспективы CLR ovalue
и Refvalue
имеют идентичную семантику и обрабатываются так же.
Андрей правильный; Я просто добавлю пару дополнительных деталей.
Во-первых, правильный способ подумать о параметрах OUT / REF заключается в том, что они являются псевдонимами для переменных . То есть, когда у вас есть метод m (ref int q) и вызовите его m (ref x), q и x - это два разных имена для точно такой же переменной . Переменная - это место хранения; Вы храните что-то в Q, вы храняте его в X тоже, потому что они два разных имена для того же места.
Во-вторых, альтернатива, которую вы описываете, называется ссылками «Копировать в / копировать». В этой схеме есть два места хранения, и содержимое одного скопированы на начало вызова функции и копировали обратно, когда его сделано. Как вы отмечаете, семантика копирования копирования отличается от семантики ссылок на псевдоним, когда исключены исключения.
Они также различны в причудливых ситуациях, такими, как это:
void M(ref int q, ref int r)
{
q = 10;
r = 20;
print (q);
}
...
M(ref x, ref x);
в псевдонимах, x, q и r - это одно и то же место для хранения, поэтому эти отпечатки 20. В ссылке на копирование в копировании это будет печатать 10 И окончательная стоимость X будет зависеть от того, остался ли копирование вправо или направо налево.
Наконец, если я правильно вспомнил, есть редкие и странные сценарии в реализации деревьев выражения, где мы фактически реализуем семантику для копирования в параметрах REF. Я должен просмотреть этот код и посмотреть, смогу ли я вспомнить, что именно эти сценарии.