Главная » C# » Ограничения обычных типов в Visual C# (Sharp)

0

Ограничения при использовании обычных типов порождаются тем обстоятельсом, что  при операциях присваивания значения одной переменной другой данные копируются. Это оказывает влияние на то, что происходит при внедрении ссылоых типов в обычные типы и при использовании обычных типов в качестве паретров для методов.

Эффекты, вызываемые копированием данных

Когда одна переменная пользовательского обычного типа присваивается другой переменной этого типа, содержимое первой переменной копируется во вторую. Чтобы увидеть этот процесс в действии, рассмотрим сначала, как объявляются пользовательские типы. Этот процесс показан на рис. 4.4.

Рис. 4.4. Объявление пользовательских типов

При объявлении пользовательских типов элементы данных и методы объявляются между фигурными  скобками  ({}).  Объявление  можно  рассматривать  как  надпись на ящике, фигурные скобки — как ящик, а все, что в фигурных скобках, — как сержимое ящика. Все, что находится в фигурных скобках, является телом типа. Идентификатор перед первой фигурной скобкой называется именем типа.

В том виде, в  котором типы объявлены  на рис. 4.4,  они  не  имеют идентификата области видимости. Область видимости можно рассматривать как определение,

кто  имеет  доступ  к  вашим  карманам  и  бумажнику.  Область  видимости  типов в примере подобна ситуации, когда только ваша жена, и никто другой, имеет право проверять содержимое вашего бумажника.

Но если бы перед идентификатором типов было поставлено  ключевое  слово public , тогда пользовательский тип был бы доступен всем компонентам програы, как будто бы кто угодно имел право проверять содержимое вашего бумажника. В случае бумажника, устанавливать общую область видимости — не очень хорая идея, но когда доступ к области видимости можно контролировать, то для тов такая  область  видимости  иногда может быть желаемой.  Это  можно сравнить с оплатой кредитной карточкой, когда вы отдаете ее кассиру для осуществления транзакции. В этом случае вы предоставляете доступ к части своего бумажника, но под вашим контролем.

Теперь рассмотрим код на рис. 4.5. В нем создается и присваивается переменной экземпляр типа MyVaiueType, после чего значение первой переменной присваиваея другой переменной такого же типа.

Рис. 4.5. Применение пользовательского обычного типа

Пример на рис. 4.5 иллюстрирует, что происходит с двумя переменными, когда создается экземпляр одной из них, который присваивается другой переменной, пле чего вторая переменная модифицируется. Необходимо понимать, каким обром модифицируется каждый тип при взаимодействии с другим типом.

Для сравнения, те же самые операции можно выполнить со ссылочным типом, как показано в следующем коде:

MyReferenceType val = new MyReferenceType(); MyReferenceType copiedVal = val;

Console.WriteLine("val value=" + val.value +

"                    copiedVal value=" + copiedVal.value);

val.value = 10;

Console.WriteLine("val value=" + val.value +

"                    copiedVal value=" + copiedVal.value);

Значит, если два фрагмента кода функционально идентичны, с единственной раицей, заключающейся в виде типов (обычный по сравнению со ссылочным), то они выдадут одинаковые результаты? Выполнив оба фрагмента кода, мы получим следующие результаты:

var value=0  copiedVar value=0 var value=10 copiedVar value=0 val value=0  copiedVal value=0 val value=10 copiedVal value=10

Как можно видеть из этих результатов, два функционально одинаковых фрагмента кода, отличающиеся только видом типа переменной, выдают совершенно разные результаты:

•    когда присваивается и модифицируется значение переменной обычного типа, то изменяется только содержимое модифицируемой переменной;

•    когда присваивается и модифицируется значение переменной ссылочного типа, изменяется содержимое как первоначальной, так и присваиваемой переменной.

Этот пример демонстрирует, что при определении пользовательских типов данных необходимо быть осторожным при обращении с обычными и ссылочными типами.

Как мы узнали в главе 2, обычные типы сохраняются в стеке. Таким образом, обвление переменной пользовательского обычного типа означает, что все содержое данной переменной сохраняется в стеке, и после присваивания значения одной переменной обычного типа другой переменной обычного типа полностью копиртся все содержимое первой переменной. Происходящее было очевидно в нашем примере, когда были использованы простые числовые типы (такие как double), но результат копирования структур со всех их содержимым может быть далек от того, который вы ожидали.

Источник: Гросс  К. С# 2008:  Пер. с англ. — СПб.:  БХВ-Петербург, 2009. — 576 е.:  ил. — (Самоучитель)

По теме:

  • Комментарии