Вам нужен параметр ref или out? - PullRequest
2 голосов
/ 13 января 2010

Я передаю экземпляр класса методу, и этот метод изменяет экземпляр.

Нужно ли использовать ключевое слово out или ref, поскольку этот класс я передаю?

Вот что я хочу сделать:

public void Blah()
{
   Blah b = Dao.GetBlah(23);

   SomeService.ModifyXml(b);    // do I need to use out or ref here?

   Dao.SaveXml(b.xml);

}

Ответы [ 5 ]

14 голосов
/ 13 января 2010

Правильный способ думать об этом: используйте ref / out, когда вы хотите создать псевдоним для переменной . То есть когда вы говорите:

void M(ref int x) { x = 10; }
...
int q = 123;
M(ref q);

что вы говорите: "x - это другое имя переменной q" . Любые изменения в содержимом x изменяют q, а любые изменения в содержимом q изменяют x, потому что x и q - это просто два имени для точно такого же места хранения .

Обратите внимание, что это полностью отличается от двух переменных, относящихся к одному и тому же объекту:

object y = "hello";
object z = y;

Здесь у нас есть две переменные , каждая переменная имеет одно имя , каждая переменная относится к один объект , и обе переменные относятся к тот же объект . В предыдущем примере у нас есть только одна переменная с двумя именами .

Это ясно?

5 голосов
/ 13 января 2010

Если ссылка b не изменяется, и изменяются только свойства b, вам не нужно ни ref, ни out. Оба из них будут оценены только в том случае, если будет изменена сама ссылка.

Я немного расширил ваш пример кода, чтобы включить использование для ref, out и ни для одного:

http://pastebin.ca/1749793

[Снип]

public void Run()
{
    Blah b = Dao.GetBlah(23);

    SomeService.ModifyXml(b);    // do I need to use out or ref here?
    Dao.SaveXml(b.Xml);

    SomeService.SubstituteNew(out b);
    Dao.SaveXml(b.Xml);

    SomeService.ReadThenReplace(ref b);
    Dao.SaveXml(b.Xml);
}

Остальная часть кода находится в этой PasteBin.

1 голос
/ 13 января 2010

Нет, ты не. Поведение по умолчанию при передаче экземпляра ссылочного типа в качестве параметра заключается в передаче его ссылки по значению. Это означает, что вы можете изменить текущий экземпляр, но не менять его на другой другой экземпляр. Если это то, что вы имеете в виду под «изменить экземпляр», то вам не нужно ref или out.

1 голос
/ 13 января 2010

Нет, вы не хотите реф или здесь. Вы хотите использовать ref, когда метод изменит объект, на который указывает параметр. Вы хотите использовать, когда метод всегда будет указывать новый объект, на который будет указывать параметр.

0 голосов
/ 13 января 2010

Простой способ проверить это с помощью intellisense: наведите указатель мыши на ModifyXml, и если параметр в сигнатуре метода содержит out, например, ModifyXml( out Blah blah ), вам нужно ключевое слово out.То же самое касается ref.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...