Информация об изменениях

Сообщение Re[13]: ref local vs null от 29.05.2019 22:18

Изменено 29.05.2019 22:42 alexzzzz

Re[13]: ref local vs null
Здравствуйте, vdimas, Вы писали:

A>>>>Максимум что можно сделать с самой ссылкой, перенаправить её в новое место, явно указав, куда именно;

V>>>Также с указателями, заметь.
V>>>В С++ с ссылками так поступать нельзя.
A>>Потому что текущий синтаксис не позволяет отличить переназначение ссылки от присваивания. Есть более концептуальные причины?

V>Это и есть причина.

V>Синтаксис должен отражать семантику.
V>Ты же пытаешься поставить телегу впереди лошади.

Я не вижу, кто тут телега и кто лошадь. Ты упомянул, что «в отличие от C++, ref-переменные в C# имеют семантику не ссылок, а именно указателей, бо в С++ ссылка — это алиас, а в C# — значение». Я этого не понял. Когда учил С++, помню, долго не мог въехать в ссылки, зачем они нужны, если уже есть указатели. В объявлении ссылки используется значок '&', который как бы намекает на получение адреса, что как бы намекает, что это что-то типа указателя и можно использовать вместо указателей. Непонятно только, в чём выгода. Понял позже ― указатель смотрит куда хочет, а нормальная ссылка только туда, куда можно смотреть. Чтобы прочитать или, не дай бог, записать что-то по адресу указателя, сначала стоит перекреститься, а ссылки безопасны.

Если судить о семантике по синтаксису, ссылки в C# отличаются от указателей кардинально. Указатели — почти такой же тип как и value- и reference-типы. Объявляется так же, значения присваиваются тем же оператором. В объявлении же ссылки сначала обязательно будет 'ref' (никакого оператора получения адреса!), инициализация/перенаправление делается отдельным оператором '=ref'. Можно иметь ссылку на указатель. Иметь указатель на ссылку нельзя, получится просто указатель на объект. Ссылка ведёт себя как сам объект, на который она ссылается. Даёт одинаковое значение при чтении, одинаковый эффект при записи, адреса переменной и ссылки на неё одинаковые. Ну это алиас, который и объявлен был явно как алиас и ведёт себя как алиас.

Т.е. непонятно, в чём семантическое отличие от ссылок в C++? Если только в том, что в C++ нельзя переназначить ссылку/алиас на другой объект, то это чисто синтаксическая проблема С++. В нём инициализация ссылки выполняется оператором присваивания и повторно этот фокус не работает (хотя, я посмотрел, народ на SO пытается, в первый раз же получилось!).

A>>Почему оно не на C#?

V>А на чём?

Точно на чём-то другом.
https://github.com/dotnet/corefx/blob/master/src/System.Runtime.CompilerServices.Unsafe/src/System.Runtime.CompilerServices.Unsafe.il

V>Ссылки я дал — проверь сам.

Ссылки на System.Runtime.CompilerServices.Unsafe? Я его сам иногда использую для вещей, которые на C# трудно выразить.
Re[13]: ref local vs null
Здравствуйте, vdimas, Вы писали:

A>>>>Максимум что можно сделать с самой ссылкой, перенаправить её в новое место, явно указав, куда именно;

V>>>Также с указателями, заметь.
V>>>В С++ с ссылками так поступать нельзя.
A>>Потому что текущий синтаксис не позволяет отличить переназначение ссылки от присваивания. Есть более концептуальные причины?

V>Это и есть причина.

V>Синтаксис должен отражать семантику.
V>Ты же пытаешься поставить телегу впереди лошади.

Я не вижу, кто тут телега и кто лошадь. Ты упомянул, что «в отличие от C++, ref-переменные в C# имеют семантику не ссылок, а именно указателей, бо в С++ ссылка — это алиас, а в C# — значение». Я этого не понял. Когда учил С++, помню, долго не мог въехать в ссылки, зачем они нужны, если уже есть указатели. В объявлении ссылки используется значок '&', который как бы намекает на получение адреса, что как бы намекает, что это что-то типа указателя и можно использовать вместо указателей. Непонятно только, в чём выгода. Понял позже ― указатель смотрит куда хочет, а нормальная ссылка только туда, куда можно смотреть. Чтобы прочитать или, не дай бог, записать что-то по адресу указателя, сначала стоит перекреститься, а ссылки безопасны.

Если судить о семантике по синтаксису, ссылки в C# отличаются от указателей кардинально. Указатели — почти такой же тип как и value- и reference-типы. Объявляется так же, значения присваиваются тем же оператором. В объявлении же ссылки сначала обязательно будет 'ref' (никакого оператора получения адреса!), инициализация/перенаправление делается отдельным оператором '=ref'. Указателю можно присвоить всё что хочешь, можно ничего не присваивать, а ссылку можно направить только на существующий объект. Можно иметь ссылку на указатель. Иметь указатель на ссылку нельзя, получится просто указатель на объект. Ссылка ведёт себя как сам объект, на который она ссылается. Даёт одинаковое значение при чтении, одинаковый эффект при записи, адреса переменной и ссылки на неё одинаковые. Ну это алиас, который и объявлен был явно как алиас и ведёт себя как алиас.

Т.е. непонятно, в чём семантическое отличие от ссылок в C++? Если только в том, что в C++ нельзя переназначить ссылку/алиас на другой объект, то это чисто синтаксическая проблема С++. В нём инициализация ссылки выполняется оператором присваивания и повторно этот фокус не работает (хотя, я посмотрел, народ на SO пытается, в первый раз же получилось!).

A>>Почему оно не на C#?

V>А на чём?

Точно на чём-то другом.
https://github.com/dotnet/corefx/blob/master/src/System.Runtime.CompilerServices.Unsafe/src/System.Runtime.CompilerServices.Unsafe.il

V>Ссылки я дал — проверь сам.

Ссылки на System.Runtime.CompilerServices.Unsafe? Я его сам иногда использую для вещей, которые на C# трудно выразить.