Задание типа ссылки на тип null не влияет на тип копирования - PullRequest
8 голосов
/ 09 ноября 2011

Почему при этом получается "0"?

object a = 0;
object b = a;
a = null;
Console.WriteLine(b.ToString()); // Produces "0"
Console.Read();

Разве b не указывает на то же место, а установка a = null фактически делает b нулевым?

Ответы [ 5 ]

28 голосов
/ 09 ноября 2011

Картинка стоит тысячи слов:

enter image description here

20 голосов
/ 09 ноября 2011

Вы хотите знать, где находятся файлы cookie.У вас есть лист бумаги с надписью «А».На бумаге карандашом написано «Улица Сезам 123».

Бумага не является печеньем.Адрес не является cookie.Бумага содержит ссылку на адрес, который содержит cookie.

Вы получаете второй лист бумаги, помеченный буквой «B».На этом листе бумаги вы делаете копию содержимого «А».Теперь у вас есть два клочка бумаги, оба говорят «Улица Сезам 123».Оба сообщают вам, где находятся файлы cookie.

Вы берете листок бумаги "А" и стираете его.«А» больше не относится к местоположению файлов cookie. B все еще делает.

Вы предполагаете, что "b = a" означает, что вы пишете на B "для определения местоположения файлов cookie, пожалуйста, обратитесь к статье A".Но это не то, что означает «b = a» в C #;это означает сделать копию ссылки , а не сделать псевдоним ссылки .

В C # для создания псевдонима ссылки вы используете "ref"ключевое слово, достаточно запутанно:

void M(ref object b)
{
    b = null;
}
...
object a = 0;
M(ref a);
// "b" now becomes an alias for "a"; when "b" is nulled out, so is "a" because they are the same variable with two different names.

В C # вы можете сделать это только при вызове метода, который принимает параметр ref, подобный этому.Функция, которую вы хотите, не поддерживается в C #, хотя мы рассматривали возможность ее поддержки:

object a = 0;
ref object b = ref a;
a = null; // b and a are aliases for the same variable now.

Есть ли у вас настоятельная необходимость в этой функции?Если вы это сделаете, пожалуйста, дайте мне знать, что это такое.Это поможет нам определить, стоит ли использовать эту функцию в гипотетической будущей версии C #.

ОБНОВЛЕНИЕ: Это сделано!Эта функция была добавлена ​​в C # 7.

6 голосов
/ 09 ноября 2011

Вы устанавливаете ссылка обнулить, вы не меняя объект опорных точек до . a и b являются двумя отдельными ссылками, поэтому установка a на null, конечно, оставит b без изменений (подумайте «указатель»), это просто означает, что теперь указывает на null («никуда» «).

3 голосов
/ 09 ноября 2011

Бокс (это процесс, который здесь происходит) довольно хорошо объяснен в следующей статье с примерами того, что происходит в памяти.

1 голос
/ 09 ноября 2011

Вот описание того, что происходит:

object a = 0; // pointer a = 0xSomeA
object b = a; // pointer b = 0xSomeB
a = null; // nulling a, now 0x00; b still the same
...