- PVSM.RU - https://www.pvsm.ru -
В C# все типы объявленные с ключевым словом struct являются значимыми, как class — ссылочными. Разницы в их поведении не наблюдается, поэтому особо важно понимать какой тип используется в программе, так как это может значительно влиять на производительность в программе.
Рассмотрим пример, из которого видна разница между ссылочными и значимыми типами:
//Ссылочный тип, так как объявлено class
class Reference
{
public Int32 x {get; set;} // здесь используется сокращенный метод объявления свойств, подробнее читайте книгу "Библия С#" М. Фленова
}
//Значимый тип, так как объявлено struct
struct Structure
{
public Int32 x {get; set;}
}
static void Main()
{
Reference r1 = new Reference(); //размещается в куче
Structure s1 = new Structure(); //размещается в стеке
r1.x = 5; //разыменование указателя (обращения к значению в памяти, на которое указывает указатель, подробнее операции над указателями)
s1.x = 10; //изменения в стеке
Console.WriteLine(r1.x); // вывод 5
Console.WriteLine(s1.x); //вывод 10
Reference r2 = r1; //копируется только ссылка, указатель
Structure s2 = s2; //помещается в стек и копируются поля
r1.x = 8 // изменяется и r1.x и r2.x
s1.x = 9 // изменяется только s1.x, но не s2.x
Console.WriteLine(r1.x); // вывод 8
Console.WriteLine(r2.x); //вывод8
Console.WriteLine(s1.x); // вывод 9
Console.WriteLine(s2.x); //вывод 10
}
Как видно из примера, можно заметить, что при работе с ссылочными и значимыми типами наблюдается существенная разница. При создании ссылочных типов выделется память в куче и возвращается адрес в памяти, который сохраняется в переменной. Поэтому при инициализации переменной такого же типа и присвоения ей того же значения, то копируется только адрес на область в памяти. Как и происходит в строке «Reference r2 = r1; //копируется только ссылка, указатель». То есть 2 переменные указывают только на одну область памяти.
В тоже время совсем другое происходит при работе со значимыми типами. При создании новой переменной значимого типа и копировании значений, происходит новое выделение в стеке памяти и создание новой независимой переменной. «Structure s2 = s2; //помещается в стек и копируются поля»
Исходя из выше сказанного можно заметить также, что при изменении полей в ссылочном типе происходит изменение значений, на которые ссылаются переменные. То есть в данном примере переменные r1.x и r2.x покажут одинаковое значение, даже если изменить к примеру r1.x, так как обе переменные указывают на одну область памяти. А вот если изменить s1.x, то изменение s2.x не последует, так как s1.x и s2.x это две разные переменные, которые никак не связаны между собой.
Немного отступим от темы, но это имеет прямое отношение к ссылочному типу. Рассмотрим такой оператор как new. С его помощью и только создаются и инициализируются все ссылочные типы. Опишу я оператор new полностью и постараюсь объяснить каждое непонятное слово.
Оператор new действует так:
Указатель на объект-тип, этот член позволяет определить тип данного объекта(экземпляра).
Этот указатель использует такой метод как .GetType(), он позволяет определить какой тип у данного объекта. Еще можно использовать выражение typeof, но об этом потом. А индекс блока синхронизации используется для хранения данных при многопоточном выполнении программы. А также используется при вызове .GetHashCode(). Подробнее можно прочитать в документации .NET «Внутреннее устройство .NET Framework — как CLR создает объекты периода выполнения».
При этом у оператора new нет пары — оператора delete. Как я писал в предыдущей статье, CLR сам занимается сборкой мусора в управляемой куче, автоматически находит ненужные объекты и уничтожает их.
Исходя из выше сказанного: проектируя свой собственный тип, проверьте, какой тип лучше всего использовать. Это помогает улучшить эффективность кода. Вот несколько условий, когда можно использовать значимый тип:
Но при этом нужно учитывать тот факт, что поля переменных, которые являются аргументом и передаются по назначению, то они копируются, что в свою очередь приводит к снижению производительности. Поэтому, метод, возвращающий значимый тип, приводит к копированию полей экземпляра, что снижает эффективность работы программ. Следовательно, нужно еще кое-что учитывать, а именно:
Конечно, у значимых типов есть свои преимущества перед ссылочными типами, но при этом есть и недостатки. Вот некоторые особенности, отличающие ссылочные и значимые типы.
Поэтому применяя знания, нужно наиболее полно использовать все ресурсы системы, при этом не теряя производительность и экономно расходовать ресурсы.
В следующей статье рассмотрим упаковку и распаковку значимых типов.
Автор: Priest512
Источник [1]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/programmirovanie/40877
Ссылки в тексте:
[1] Источник: http://habrahabr.ru/post/190026/
Нажмите здесь для печати.