2010-06-27 2 views
3

привет ребята просто интересно взять следующий примерC# передача по значению

public void main() 
{ 

    int x = 1; 

    Foo(x); 
} 

public void Foo(int y) 
{ 
    y = 5; 
} 

Мы знаем аргументы C# передаются по значению для типов значений. Означает ли это, что в приведенном выше примере у меня есть 2 копии в стеке, один для x и один для y ??

Thanks

+0

Извините за придирчивость, но приведенный выше код не будет скомпилирован в первом случае: p – Syd

+0

Ты сейчас счастлив? –

ответ

14

Да, в стеке будет две независимые переменные. Они также будут в двух разных фреймах штабелей - один для main и один для foo (при отсутствии вставки). Когда Foo возвращает значение x все равно будет 1, а не 5.

В самом деле, аргументы всегда передается по значению по умолчанию в C#, как для ссылочных типов и типов значений. Единственное различие заключается в том, что для ссылочных типов значение аргумента равно Ссылка - не сам объект.

См. Мои article on parameter passing для получения более подробной информации об этом.

Обратите внимание, что фактическое поведение того, что происходит в стеке, это implementation detail: компилятор C# должен убедиться, что программа ведет себя так, как определено в спецификации, но это не указывает на поведение стека или кучи. Таким образом, x должен иметь значение 1 в конце вашего кода, но действительный компилятор C# может положил и x, и y на кучу.

+0

Спасибо, Джон, я чувствую себя пораженным звездами, великий Джон Скит. Не могу дождаться вашей будущей книги. Вопрос о встраивании, как компилятор решает, следует ли встраивать вызов метода или нет? –

+0

Или они не могли идти ни в стек, ни в кучу; было бы вполне разумно (1) генерировать код, который помещает это в регистры, или (2) генерировать * никакой код вообще *, поскольку этот код ничего не делает и не имеет побочных эффектов, и это можно определить в jit time. –

+2

@ ash2010: Компилятор C# не строит ничего. Компилятор JIT делает inlining, и в CLR v4 он расскажет вам, когда он решил сделать inlining! http://blogs.msdn.com/b/clrcodegeneration/archive/2009/05/11/jit-etw-tracing-in-net-framework-4.aspx –

4

Вы правильно поняли - значение для x будет положить на стек в кадре стека для функции main, а значение y будет помещен в стек в кадре стека для Foo.

1

Для получения дополнительной информации вам также необходимо понять, как передаются значения параметров. Причина, по которой y в Foo не влияет на x в Main, заключается в том, что они находятся в разных кадрах стека. Более подробная информация о передаваемых параметрах типа значений: HERE.

+0

Я не могу сказать, что я увлекаюсь этой страницей , Например, он вызывает специфические типы значений и говорит: «Поэтому передача переменной типа значения в метод означает передачу копии переменной методу». Это верно и для ссылочных типов. (Ну, предполагая, что это означает копию значения переменной * - это, конечно же, не копирование самой переменной). Это просто для переменной ссылочного типа, значение является ссылкой. Это значение по-прежнему копируется по умолчанию ... –

Смежные вопросы