C # out-параметр - PullRequest
       31

C # out-параметр

1 голос
/ 19 сентября 2011

В чем разница между следующими двумя фрагментами кода?

public void foo(out classA x)
{
    y = new classA();
    x = y;
}

и вторым:

public void foo(out classA x)
{
    classA y;
    x = y;
}

Правда ли, что второй фрагмент опасен, потому что xтеперь имеет ссылку на этот локальный y, который может быть уже мертв после выхода из foo?

Почему мы вообще должны использовать «new»?

Янемного запутано, потому что в C ++, если x во втором фрагменте будет указателем, оператор x = y даже не скомпилируется, так как y не является указателем.

Ответы [ 4 ]

4 голосов
/ 19 сентября 2011

Давайте на минутку предположим, что второй фрагмент -

public void foo(out classA x)
{
  classA y = new classA();
  x = y;
}

Фрагмент, который вы написали, вообще не компилируется в C #.y должен быть назначен первым.Строка classA y; не создает экземпляр classA в стеке, как в C ++.Он просто объявляет переменную y типа classA.

. С учетом фрагмента компиляции назначение переменной out локально объявленному и инициализированному объекту никоим образом не опасно.Объект classA, на который указывает y и который назначен на x, будет оставаться живым и исправным, пока x не выйдет из области видимости, где бы он не был объявлен / использован.

2 голосов
/ 19 сентября 2011

Ваша путаница, я думаю, заключается в том, что во втором примере C ++ возвращает ссылку на объект, выделенный из стека.Этого не происходит в C #.

Учитывая ваш второй пример в C #:

public void foo(out classA x)
{
  classA y;  // Doesn't allocate an object
  x = y;
}

В любом случае это, вероятно, не будет компилироваться, потому что y никогда не присваивается значение.

1 голос
/ 19 сентября 2011

Это не опасно, потому что код НЕ сможет быть скомпилирован, пока все параметры "out" не будут определены до того, как метод вернется или выйдет.

1 голос
/ 19 сентября 2011

Правда ли, что второй фрагмент опасен [...]

Не в C #; Вы думаете о родных языках, таких как C или C ++, которые позволяют получить указатель на локальную переменную. В C # все (в пределах разумного) является ссылкой на управляемый объект. Все по существу в куче.

...