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

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

<b>    x = BoxingDemo.Sqr(x) ;</b>

<b>    Console.WriteLine(&quot;Значение x в квадрате равно: &quot; + x);</b>

<b>  }</b>

<b>  static int Sqr(object о) { </b>

<b>    return (int)о * (int)о;</b>

<b>  }</b>

<b>}</b>

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

<b>Значение х равно: 10</b>

<b>Значение х в квадрате равно: 100</b>

В данном примере значение переменной х автоматически упаковывается при передаче методу Sqr().

Упаковка и распаковка позволяют полностью унифицировать систему типов в С#. Благодаря тому что все типы являются производными от класса object, ссылка на значение любого типа может быть просто присвоена переменной ссылочного типа object, а все остальное возьмут на себя упаковка и распаковка. Более того, методы класса object оказываются доступными всем типам, поскольку они являются производными от этого класса. В качестве примера рассмотрим довольно любопытную программу.

<b>// Благодаря упаковке становится возможным вызов </b>

<b>//методов по значению! </b>

<b>using System;</b>

<b>class MethOnValue {</b>

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

<b>    Console.WriteLine(10.ToString() ) ;</b>

<b>  }</b>

<b>}</b>

В результате выполнения этой программы выводится значение 10. Дело в том, что метод ToString() возвращает строковое представление объекта, для которого он вызывается. В данном случае строковым представлением значения 10 как вызывающего объекта является само значение 10!

Если object является базовым классом для всех остальных типов и упаковка значений простых типов происходит автоматически, то класс object можно вполне использовать в качестве "универсального" типа данных. Для примера рассмотрим программу, в которой сначала создается массив типа object, элементам которого затем присваиваются значения различных типов данных.

<b>// Использовать класс object для создания массива &quot;обобщенного&quot; типа.</b>

<b>using System;</b>

<b>class GenericDemo { </b>

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

<b>    object[] ga = new object[10];</b>

<b>    // Сохранить целые значения, </b>

<b>    for (int i=0; i &lt; 3; i++) ga[i] = i;</b>

<b>    // сохранить  значения типа double</b>

<div class="fb2-code"><code>&lt;b&gt;    for (int i=3; i &amp;lt; 6; i++) &lt;/b&gt;</code></div>

<div class="fb2-code"><code>&lt;b&gt;      ga[i] =(double) i / 2;&lt;/b&gt;</code></div>

<div class="fb2-code"><code>&lt;b&gt;    // сохранить две строки, а также значения типа bool и char&lt;/b&gt;</code></div>

<div class="fb2-code"><code>&lt;b&gt;    ga[6] = &amp;quot;Привет&amp;quot;;&lt;/b&gt;</code></div>

<div class="fb2-code"><code>&lt;div class=&quot;fb2-code&quot;&gt;&lt;code&gt;&amp;lt;div class=&amp;quot;fb2-code&amp;quot;&amp;gt;&amp;lt;code&amp;gt;&amp;amp;lt;b&amp;amp;gt;    ga[7] = true;&amp;amp;lt;/b&amp;amp;gt;&amp;lt;/code&amp;gt;&amp;lt;/div&amp;gt;&lt;/code&gt;&lt;/div&gt;</code></div>

<div class="fb2-code"><code>&lt;b&gt;    ga[8] = 'X';&lt;/b&gt;</code></div>

<b>    ga[9] = &quot;Конец&quot;;</b>

<b>    for(int i = 0; i &lt; ga.Length; i++)</b>

<b>      Console.WriteLine(&quot;ga[&quot; + i + &quot;]: &quot; + ga[i] + &quot; &quot;);</b>

<b>}</b>

<b>}</b>

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

<b>ga[0] : 0 </b>

<b>ga[1] : 1</b>

<b>ga[2] : 2</b>

<b>ga[3] : 1.5</b>

<b>ga[4] : 2</b>

<b>ga[5] : 2.5</b>

<b>ga[6] : Привет</b>

<b>ga[7] : True</b>

<b>ga[8] : X</b>

<b>ga[9] : Конец</b>

Как показывает данный пример, по ссылке на объект класса object можно обращаться к данным любого типа, поскольку в переменной ссылочного типа object допускается хранить ссылку на данные всех остальных типов. Следовательно, в массиве типа object из рассматриваемого здесь примера можно сохранить данные практически любого типа. В развитие этой идеи можно было бы, например, без особого труда создать класс стека со ссылками на объекты класса object. Это позволило бы хранить в стеке данные любого типа.