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

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

Модификатор доступа internal можно применять к классам и их членам, а также к структурам и членам структур. Кроме того, модификатор internal разрешается использовать в объявлениях интерфейсов и перечислений.

Из модификаторов protected и internal можно составить спаренный модификатор доступа protected internal. Уровень доступа protected internal может быть задан только для членов класса. Член, объявленный как protected internal, доступен лишь в пределах собственной сборки или для производных типов.

Ниже приведен пример применения модификатора доступа internal.

<b>// Использовать модификатор доступа internal.</b>

<b>using System;</b>

<b>class InternalTest {</b>

<b>  internal int x;</b>

<b>}</b>

<b>class InternalDemo {</b>

<b>  static void Main() {</b>

<b>    InternalTest ob = new InternalTest();</b>

<b>    ob.x = 10; // доступно, потому что находится в том же файле </b>

<b>    Console.WriteLine(&quot;Значение ob.x: &quot; + ob.x);</b>

<b>  }</b>

<b>}</b>

В классе InternalTest поле х объявляется как internal. Это означает, что поле х доступно в самой программе, но, как показывает код класса InternalDemo, оно недоступно за пределами программы.

ГЛАВА 17 Динамическая идентификация типов, рефлексия и атрибуты

В этой главе рассматриваются три эффективных средства: динамическая идентификация типов, рефлексия и атрибуты. Динамическая идентификация типов представляет собой механизм, позволяющий определить тип данных во время выполнения программы. Рефлексия — это средство для получения сведений о типе данных. Используя эти сведения, можно конструировать и применять объекты во время выполнения. Это довольно эффективное средство, поскольку оно дает возможность расширять функции программы динамически, т.е. в процессе ее выполнения. Атрибут описывает характеристики определенного элемента программы на С#. Атрибуты можно, в частности, указать для классов, методов и полей. Во время выполнения программы разрешается опрашивать атрибуты для получения сведений о них. Для этой цели в атрибутах используется динамическая идентификация типов и рефлексия.

Динамическая идентификация типов

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

Для поддержки динамической идентификации типов в C# предусмотрены три ключевых слова: is, as и typeof. Каждое из этих ключевых слов рассматривается далее по очереди.

Конкретный тип объекта можно определить с помощью оператора is. Ниже приведена его общая форма:

<b>выражение is тип</b>

где выражение обозначает отдельное выражение, описывающее объект, тип которого проверяется. Если выражение имеет совместимый или такой же тип, как и проверяемый тип, то результат этой операции получается истинным, в противном случае — ложным. Так, результат будет истинным, если выражение имеет проверяемый тип в той или иной форме. В операторе is оба типа определяются как совместимые, если они одного и того же типа или если предусмотрено преобразование ссылок, упаковка или распаковка.

Ниже приведен пример применения оператора is.

<b>// Продемонстрировать применение оператора is.</b>

<b>using System;</b>

<b>class A {} </b>

<b>class В : A {}</b>

<b>class UseIs {</b>

<b>  static void Main() {</b>

<b>    A a = new A();</b>

<b>    В b = new В();</b>

<b>    if (a is A)</b>

<b>      Console.WriteLine(&quot;а имеет тип A&quot;);</b>

<b>    if(b is A)</b>

<b>      Console.WriteLine (&quot;b совместим с А, поскольку он производный от А&quot;);</b>

<b>    if(a is В)</b>

<b>      Console.WriteLine(&quot;Не выводится, поскольку а не производный от В&quot;);</b>

<b>    if(b is В)</b>

<b>      Console.WriteLine(&quot;В имеет тип В&quot;);</b>

<b>    if(a is object)</b>

<b>      Console.WriteLine(&quot;а имеет тип object&quot;);</b>

<b>  }</b>

<b>}</b>

Вот к какому результату приводит выполнение этого кода.

<b>а имеет тип А</b>

<b>b совместим с А, поскольку он производный от А</b>

<b>b имеет тип В </b>

<b>а имеет тип object</b>

Большая часть выражений is в приведенном выше примере не требует пояснений, но два из них необходимо все же разъяснить. Прежде всего, обратите внимание на следующую строку кода.