Зачем мне передавать строки по ссылке на мою функцию подкачки? - PullRequest
3 голосов
/ 22 декабря 2011

В C # строка является ссылочным типом.Тогда

Зачем мне нужна своп-функция, чтобы иметь параметры ref?

swap(ref string first, ref string second) //swap(string first, string second) doesn't work
{
     temp = first;
     first = second
     second = temp;
}

Ответы [ 6 ]

7 голосов
/ 22 декабря 2011

Вы путаете два разных типа ссылок. Строки являются ссылками на экземпляры . Ваша функция подкачки принимает ссылки на переменные .

Думайте об этом так. У вас есть две книги, "Рождественская песнь в прозе" и "Пиквикские бумаги". Это книги; у них есть страницы, текст и еще много чего.

У вас есть десять листов бумаги. Пятерка говорит "Рождественская песнь в прозе". Пятерка говорит «Пиквикские бумаги». Документы ссылки на книги. Это не книги.

У вас есть десять ящиков с надписями A, B, C, D, E, F, G, H, I, J. Вы кладете бумаги с надписью «Рождественская песнь» в ящик от A до E и бумаги с надписью "Pickwick Papers" в ящики F через J.

Теперь вы хотите поменять местами содержимое ящиков E и I. Какую информацию вы должны предоставить обменнику? Нельзя сказать, чтобы обменять "Поменять местами ссылки на Christmas Carol для Pickwick Papers" потому что это изменило бы все десять ящиков, а не только E и I. Информация, которую вы должны предоставить своперу, это «E» и «I». Вы должны передать ссылку на две переменные ; тот факт, что сами переменные содержат ссылку на книгу, не имеет значения.

У вашего своппера есть три собственных ящика, помеченные как первый, второй и временный. Требуется два куска бумаги. Один говорит «Е», и это идет в ящике с надписью «первый». Один говорит «я», и это входит в ящик с надписью «второй».

Своппер смотрит «первым» и находит бумагу с надписью «E». Он смотрит в «E» и находит бумагу с надписью «Christmas Carol». Он делает ксерокопию этой бумаги и помещает копию в «временную» ... и вы видите, как это происходит отсюда, я надеюсь.

3 голосов
/ 22 декабря 2011

Да, string является ссылочным типом, и этот

void swap(string first, string second)

передает ссылки на объекты string в функцию.Но string является неизменным, поэтому функция подкачки не может изменять объекты с помощью этих ссылок.Для строк единственным способом реализации функции подкачки является использование ключевого слова ref для передачи ссылок по ссылке, чтобы ссылки можно было поменять местами.

OTOH, если у вас есть изменяемый класс, вы можете написать свопФункция без использования ключевого слова ref:

class Foo
{
    public int Bar { get; set; }
}

static void Swap(Foo first, Foo second)
{
    var temp = first.Bar;
    first.Bar = second.Bar;
    second.Bar = temp;
}

Foo foo1 = new Foo { Bar = 1 };
Foo foo1Copy = foo1;
Foo foo2 = new Foo { Bar = 2 };
Swap(foo1, foo2);

Но обратите внимание, что после замены foo1Copy.Bar == 2, поскольку объект, на который ссылаются foo1 и foo1Copy, был изменен.

3 голосов
/ 22 декабря 2011

Ссылка на строку передается по значению. Существует большая разница между передачей ссылки по значению и передачей объекта по ссылке. К сожалению, слово «ссылка» используется в обоих случаях.

3 голосов
/ 22 декабря 2011

Поскольку параметры в C # по умолчанию передаются по значению, а не по ссылке. Добавление ref дает вам поведение при передаче по ссылке.

0 голосов
/ 22 декабря 2011

String является ссылочным типом. По умолчанию он передается в метод по значению. Если вы действительно хотите изменить значение строки, вам нужно передать его по ссылке. Следующая статья MSDN объясняет это в деталях. http://msdn.microsoft.com/en-us/library/s6938f28(v=vs.80).aspx

0 голосов
/ 22 декабря 2011

Если вы передаете объект в метод, вы передаете фактический объект, а не адрес в памяти объекта.После этого вы не могли бы присвоить ему новое значение, так как изменили бы, какой объект хранится в адресе памяти в другом месте, а не в оригинале.

Добавляя ключевое слово ref, вы передаете объекты по ссылке.Это означает, что вы по существу предоставляете методу доступ к адресу, на котором хранятся объекты, поэтому при замене объектов исходные адреса памяти будут ссылаться на поменяемый объект.

...