Страница 181 из 502
<b> b.x = 30;</b>
<b> Console.WriteLine("a.x {0}, b.x {1}", a.x, b.x);</b>
<b> }</b>
<b>}</b>
Вот к какому результату приводит выполнение этой программы.
<b>а.х 10, b.x 20 а.х 20, b.x 30</b>
Как показывает приведенный выше результат, после присваивания
<b>а = b;</b>
переменные структуры а и b по-прежнему остаются совершенно обособленными, т.е. переменная а не указывает на переменную b и никак не связана с ней, помимо того, что она содержит копию значения переменной b. Ситуация была бы совсем иной, если бы переменные а и b были ссылочного типа, указывая на объекты определенного класса. В качестве примера ниже приведен вариант предыдущей программы, где демонстрируется присваивание переменных ссылки на объекты определенного класса.
<b>// Использовать ссылки на объекты определенного класса,</b>
<b>using System;</b>
<b>// Создать класс,</b>
<b>class MyClass {</b>
<b> public int x;</b>
<b>}</b>
<b>// Показать присваивание разных объектов данного класса,</b>
<b>class ClassAssignment {</b>
<b> static void Main() {</b>
<b> MyClass a = new MyClass();</b>
<b> MyClass b = new MyClass();</b>
<b> a.x = 10;</b>
<b> b.x = 20;</b>
<b> Console.WriteLine("a.x {0}, b.x {1}", a.x, b.x);</b>
<b> a = b;</b>
<b> b.x = 30;</b>
<b> Console.WriteLine("а.х {0}, b.x {1}", a.x, b.x);</b>
<b> }</b>
<b>}</b>
Выполнение этой программы приводит к следующему результату.
<b>а.х 10, b.х 20 а.х 30, b.х 30</b>
Как видите, после того как переменная b будет присвоена переменной а, обе переменные станут указывать на один и тот же объект, т.е. на тот объект, на который первоначально указывала переменная b.
В связи с изложенным выше возникает резонный вопрос: зачем в C# включена структура, если она обладает более скромными возможностями, чем класс? Ответ на этот вопрос заключается в повышении эффективности и производительности программ. Структуры относятся к типам значений, и поэтому ими можно оперировать непосредственно, а не по ссылке. Следовательно, для работы со структурой вообще не требуется переменная ссылочного типа, а это означает в ряде случаев существенную экономию оперативной памяти. Более того, работа со структурой не приводит к ухудшению производительности, столь характерному для обращения к объекту класса. Ведь доступ к структуре осуществляется непосредственно, а к объектам — по ссылке, поскольку классы относятся к данным ссылочного типа. Косвенный характер доступа к объектам подразумевает дополнительные издержки вычислительных ресурсов на каждый такой доступ, тогда как обращение к структурам не влечет за собой подобные издержки. И вообще, если нужно просто сохранить группу связанных вместе данных, не требующих наследования и обращения по ссылке, то с точки зрения производительности для них лучше выбрать структуру.
Ниже приведен еще один пример, демонстрирующий применение структуры на практике. В этом примере из области электронной коммерции имитируется запись транзакции. Каждая такая транзакция включает в себя заголовок пакета, содержащий номер и длину пакета. После заголовка следует номер счета и сумма транзакции. Заголовок пакета представляет собой самостоятельную единицу информации, и поэтому он организуется в отдельную структуру, которая затем используется для создания записи транзакции или же информационного пакета любого другого типа.
<b>// Структуры удобны для группирования</b>
<b>//</b><b> небольших объемов данных,</b>
<b>using System;</b>
<b>// Определить структуру пакета,</b>
<b>struct PacketHeader {</b>
<b> public uint PackNum; // номер пакета</b>
<b> public ushort PackLen; // длина пакета</b>
<b>}</b>
<b>// Использовать структуру PacketHeader</b>
<b>// для создания записи транзакции</b>
<b>// в сфере электронной коммерции,</b>
<b>class Transaction {</b>
<b> static uint transacNum = 0;</b>
<b> PacketHeader ph; // ввести структуру PacketHeader</b>
<b> // в класс Transaction</b>
<b> string accountNum;</b>
<b> double amount;</b>
<b> public Transaction(string acc, double val) {</b>
<b> // создать заголовок пакета</b>
<b> ph.PackNum = transacNum++;</b>
<b> ph.PackLen =512; // произвольная длина</b>
<b> accountNum = acc; amount = val;</b>
<b> }</b>
<b> // Сымитировать транзакцию,</b>
<b> public void sendTransaction() {</b>
<b> Console.WriteLine("Пакет #: " + ph.PackNum +</b>