Добавить в цитаты Настройки чтения

Страница 181 из 502

<b>    b.x = 30;</b>

<b>    Console.WriteLine(&quot;a.x {0}, b.x {1}&quot;, 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(&quot;a.x {0}, b.x {1}&quot;, a.x, b.x);</b>

<b>    a = b;</b>

<b>    b.x = 30;</b>

<b>    Console.WriteLine(&quot;а.х {0}, b.x {1}&quot;, 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(&quot;Пакет #: &quot; + ph.PackNum +</b>