Почему 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 (ребенок). Здесь — то же самое.
В 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. Вопросы. Удастся-ли создать объекты этих классов в каком-либо методе какого-либо другого класса? Если — нет, то что нужно изменить? Как будет выглядеть объявление объектов вложенных классов? Подсказка: используйте операцию выбора (точку).
Уважаемый посетитель!
Чтобы распечатать файл, скачайте его (в формате Word).
Ссылка на скачивание - внизу страницы.