Разработка приложений на языке C#. Полезные настройки. Особые спецификаторы формата, страница 22

Почему boxing? Box — это коробка, оболочка (wrapper). Reference-тип object является wrapper class (классом-оболочкой) или влиятельным благодетелем для простенькой переменной i. Итак, более мощный объект скушал (поместил в коробку и переселил в heap) копию простой переменной. Можно ли вновь сделать ее простой и возвратить в стек? Нет, ее уже никак не возвратить (она — пища для GC), но можно в стеке создать новую переменную и скопировать в нее значение живущего в heap влиятельного объекта. Эта процедура называется unboxing.

int j = (int)o;     // int j = o;  не пройдет.  Дети не могут так поступать.

Console.WriteLine("j = " + j);

Процедура unboxing'а обязательно сопровождается приведением типов. Вспомните, вы это делали, когда присваивали указатель типа CShape (родитель) указателю типа CRect (ребенок). Здесь — то же самое.

Операции is и as

В C# появились операции is и as, которые производят преобразования совместимых типов. Сиснтаксис as таков:

expression as type

где expression — ссылочное выражение, type — переменная типа Type. Все выражение эквивалентно:

expression is type ? (type)expression : (type)null

Выражение:

expression is type

будет true, если expression не null, т.е. оно может быть приведено к типу type. Операция expression as type в C# эквивалентна операции dynamic_cast<type>(expression) в C++. Опробуйте операции as и is в файле TestAsIs.cs.

using System;

namespace MyConsole

{

partial class Program

{

  public class Poly {}   // Базовый класс

  public class Tria : Poly {} // Производный класс

  static void TestAsIs()

  {

    Console.Clear();

    Tria tria = new Tria();

    Poly poly1 = new Poly(),

      poly2 = tria;    // poly2 ссылается на объект производного класса

    Console.WriteLine("\t\tTest 'as' operator");

    Poly p = poly1 as Poly;

    Tria t = poly1 as Tria; // poly1 ссылается на объект базового класса

    Console.Write(

      "\npoly1 " + (p != null ? "is" : "is not") + " a Poly" +

      "\npoly1 " + (t != null ? "is" : "is not") + " a Tria");

    p = poly2 as Poly;

    t = poly2 as Tria;

    Console.Write(

      "\npoly2 " + (p != null ? "is" : "is not") + " a Poly" +

      "\npoly2 " + (t != null ? "is" : "is not") + " a Tria");

    Console.WriteLine("\n\n\t\tTest 'is' operator");

    Console.Write(

      "\npoly1 " + (poly1 is Poly ? "is" : "is not") + " a Poly" +

      "\npoly1 " + (poly1 is Tria ? "is" : "is not") + " a Tria" +

      "\npoly2 " + (poly2 is Poly ? "is" : "is not") + " a Poly" +

      "\npoly2 " + (poly2 is Tria ? "is" : "is not") + " a Tria");

    Console.WriteLine("\n\t\tPress any key to go to main menu\n");

    Console.ReadKey(true);

  }

}

}

Обратите внимание на следующие моменты:

·  Если вы в любом случае намерены приводить типы, то операция is не нужна (излишество),

·  Если вы собираетесь определить тип для разветвления логики программы (приведение типов не требуется), то применение операции is оправдано, операция as не нужна.

·  Объявления классов Poly и Tria вложены внутрь класса Program. Вопросы. Удастся-ли создать объекты этих классов в каком-либо методе какого-либо другого класса? Если — нет, то что нужно изменить? Как будет выглядеть объявление объектов вложенных классов? Подсказка: используйте операцию выбора (точку).

Динамические структуры данных