Страница 170 из 502
<b> x = BoxingDemo.Sqr(x) ;</b>
<b> Console.WriteLine("Значение x в квадрате равно: " + 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 для создания массива "обобщенного" типа.</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 < 3; i++) ga[i] = i;</b>
<b> // сохранить значения типа double</b>
<div class="fb2-code"><code><b> for (int i=3; i &lt; 6; i++) </b></code></div>
<div class="fb2-code"><code><b> ga[i] =(double) i / 2;</b></code></div>
<div class="fb2-code"><code><b> // сохранить две строки, а также значения типа bool и char</b></code></div>
<div class="fb2-code"><code><b> ga[6] = &quot;Привет&quot;;</b></code></div>
<div class="fb2-code"><code><div class="fb2-code"><code>&lt;div class=&quot;fb2-code&quot;&gt;&lt;code&gt;&amp;lt;b&amp;gt; ga[7] = true;&amp;lt;/b&amp;gt;&lt;/code&gt;&lt;/div&gt;</code></div></code></div>
<div class="fb2-code"><code><b> ga[8] = 'X';</b></code></div>
<b> ga[9] = "Конец";</b>
<b> for(int i = 0; i < ga.Length; i++)</b>
<b> Console.WriteLine("ga[" + i + "]: " + ga[i] + " ");</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. Это позволило бы хранить в стеке данные любого типа.