C # - Ссылка типа сравнения с путаницей указателей? - PullRequest
3 голосов
/ 29 апреля 2011

Я читаю CLR Джеффри Рихтерса через C #, и в нем он говорит с параметрами ref, что сама ссылка передается по значению.Это имеет смысл для меня и кажется аналогичным указателям.

то есть в C, если я передаю указатель на функцию и затем назначаю указатель через malloc, он меняет указатель, чтобы указывать на новое место в памяти, однако я знаюпоскольку сам указатель является копией, он не переназначает исходный указатель, который был передан в функцию.Чтобы выполнить изменение указателя вне функции, я должен использовать двойной указатель.

Однако в C #:

void Swap(ref Object a, ref Object b)
{
    Object t = b;
    b = a;
    a =t ;
}

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

Может кто-нибудь разобраться в моем замешательстве?

Ответы [ 3 ]

6 голосов
/ 29 апреля 2011

У вас это немного выключено.С ссылочными типами , ссылками передаются по значению .Передача ref параметра отличается.В

private void Frob(Foo foo) // Foo is a class
{

}

Копия ссылки на объект типа Foo на сайте вызова передается в метод Frob.Эта копия ссылки передается по значению.Эта ссылка и ссылка на сайте вызова указывают на один и тот же объект в памяти и будут продолжать работать до тех пор, пока один из них не будет указывать на некоторый другой объект в памяти.Например, если внутри этого метода мы пишем

foo = someOtherFoo;

, то параметр больше не ссылается на тот же объект, что и объект на сайте вызова.Ссылка на сайт вызова: без изменений .

Теперь рассмотрим, введем ли мы ключевое слово ref.

private void Frob(ref Foo foo)
{
    foo = someOtherFoo;
}

В этой ситуации foo является псевдонимом переменной на сайте вызова.Эти переменные не просто указывают на один и тот же объект в памяти, это как если бы они были одной и той же переменной!В результате указание foo на someOtherFoo не только изменит foo внутри этого метода, это изменение также будет отражено на сайте вызова.

5 голосов
/ 29 апреля 2011

Без ключевого слова ref ссылка на объект передается по значению.

С ключевым словом ref ссылка на ссылку на объект передается по значению.

[просто компилятор скрывает тот факт, что присвоение параметра, переданного явным ref, изменяет указатель]

0 голосов
/ 29 апреля 2011

При вызове передается исходное значение указателя (ссылка)

void Swap(ref Object a, ref Object b)
{
    Object t = b;
    b = a;
    a = t;
}

Передается копия исходного указателя:

void Swap(Object a, Object b)
{
    Object t = b;
    b = a;
    a = t;
}

Оба будут указывать на один и тот же объект, ноизменение второго не будет отражено в большем объеме, что этот метод ...

Я не совсем понимаю вопрос, хотя ...

...