Прочитайте главу Джона Скита о ссылках и ценностях. Все еще в замешательстве
Я прочитал раздел 2.3.2 книги Скита, и, насколько я понимаю, в C# нет такой вещи, как истинная ссылка, как в C++.
Интересно отметить, что не только бит "по ссылке" мифа неточен, но и бит "объекты переданы". Сами объекты никогда не передаются ни по ссылке, ни по значению. Когда задействован ссылочный тип, либо переменная передается по ссылке, либо значение аргумента (ссылка) передается по значению.
Видите, это отличается от C++ (я пришел из C++ фона), потому что в C++ вы можете использовать амперсанд для непосредственного использования объекта в списке параметров - никаких копий чего-либо, даже копии адреса памяти объекта:
bool isEven ( int & i ) { return i % 2 == 0 } )
int main ()
{
int x = 5;
std::cout << isEven(x); // is the exact same as if I had written
// std::cout (x % 2 == 0)
return 0;
}
Нет эквивалента вышеупомянутому. Лучшее, что вы можете получить в C# - это эквивалент
bool isEven ( int * i ) { return *i % 2 == 0 } )
int main ()
{
int x = 5;
std::cout << isEven(&x); // is like
// int * temp = &x;
// return *temp % 2 == 0;
// (garbage collect temp)
return 0;
}
который передает значение своего рода ссылки (указатель) и, конечно, бессмысленно в моем примере, потому что все, что передается, это маленький примитив (int
).
Из того, что я понимаю, нет синтаксиса C#, который явно обозначает элемент как ссылку, а не эквивалент &
в моем примере C++. Единственный способ узнать, имеете ли вы дело со значением или ссылкой, состоит в том, чтобы запомнить, какие типы элементов являются ссылками при копировании, а какие являются значениями. Это похоже на JavaScript в этом отношении.
Пожалуйста, критикуйте мое понимание этой концепции.
2 ответа
В C# все классы являются ссылочными типами, а все остальное (я думаю) - нет.
Здесь есть две разные концепции:
ссылочные типы, где "ссылка" - это значение, которое ссылается на экземпляр класса, и
передача по ссылке, где "ссылка" - это то, что относится к переменной.
Слово "ссылка" означает немного разные вещи в двух контекстах, и важно держать их отдельно.
IIRC, Skeet хорошо объясняет разницу между переменными, именами, значениями и различными значениями "ссылки".
(Если вы представляете переменную как блок, куда вы можете поместить вещи, а ссылки - как фрагменты строки, первая "ссылка" - это фрагмент строки, привязанный к объекту, а вторая "ссылка" - строка, связанная с блоком.)
(И эталонные параметры C++ реализуются путем передачи адреса - это самый простой и эффективный способ ссылки на что-то, хранящееся в другом месте.)
Если я правильно понял ваш вопрос, то вам будет сложно узнать, является ли это ссылкой или типом значения.
Простой способ сделать это, зная, что вы используете вызов или структуру.
Все классы являются ссылочными типами, а все структуры являются типами значений. Даже int это struct
public struct Int32
таким же образом bool также
public struct Boolean
Чтобы узнать подробности о классе, вы должны нажать "F12" на ключевое слово.