Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лекция 2. Наследование.doc
Скачиваний:
5
Добавлен:
15.11.2019
Размер:
273.92 Кб
Скачать

Приведение типов в с#

К настоящему моменту мы создали уже не одну развитую иерархию типов. При этом С# позволяет приводить (cast) один тип к другому, то есть осуществлять преобразование объектов одного типа в объекты другого типа. Рассмотрению правил приведения типов в С# и посвящен этот раздел.

Рассмотрим приведение типов на простом примере. Вспомним нашу иерархию классов сотрудников. Конечно же, на самой вершине этой иерархии стоит класс System Object — в С# все типы производятся от этого класса. Можно сказать, используя терминологию классического наследования, что все типы являются is-a-объектами. Кроме того, в нашей иерархии существуют и другие отношения классического наследования. Например, PTSalesPerson (продавец на неполный рабочий день) является is-a-продавцом Salesperson и т. д.

Первый закон приведения типов звучит так: если один класс является производным от другого, всегда безопасно ссылаться на объект производного класса через объект базового класса. В результате мы можем использовать в С# весьма мощные программные конструкции. Например, если у нас определен метод для увольнения сотрудника:

public class TheMachine

{

public static void FireThisPerson(Employee e)

{

// Удаляем сотрудника из базы данных

// Отбираем у него ключ и точилку для карандашей

}

}

В соответствии с правилами приведения типов мы можем передавать методу FireThisPerson( ) объект как самого типа Employee, так и любого производного от Employ ее типа:

// Производим сокращение персонала

TheMachine.FireThisPerson(e);

TheMachine.FireThisPerson(sp);

Этот код будет выполнен без ошибок, поскольку здесь производится неявное приведение от базового класса (Employee) к производному. Однако что, если вы также хотите уволить объект класса Manager (который в настоящее время хранится через ссылку на объект базового класса)? Если вы попробуете передать ссылку на объект (типа System.Object) нашему методу FireThisPerson( ), то вы получите сообщение об ошибке компилятора:

// Класс Manager - производный от System Object поэтому мы имеем право провести

// следующую операцию приведения

object о = new Manager("Frank Zappa", 9, 40000, “111-11-1111", 5);

TheMachine.FireThisPerson(o); // Ошибка компилятора!

Причина ошибки кроется в определении метода FireThisPerson( ), который принимает объект типа Employee. Чтобы этой ошибки не возникало, нам необходимо явно привести объект базового класса System.Object к производному типу Employee (учитывая происхождение нашего объекта о, это вполне возможно):

// Здесь будет ошибка - вначале нужно провести явное приведение типов:

// FireThisPersonO

// А вот так проблем не возникнет:

FireThisPerson((Employee)o);

Приведение числовых типов

Приведение числовых типов подчиняется примерно тем же правилам, что и приведение классов. Если вы пытаетесь привести «больший» числовой тип к «меньшему» (например, int — в byte), необходимо провести явное преобразование:

int х = 30000;

byte b -= (byte)x; // Возможна потеря данных

Нас можно поздравить: теперь мы уже умеем создавать сложные иерархии пользовательских типов в С#. Но прежде чем перейти к ним, мы должны рассмотреть еще два аспекта, тесно связанных с проектированием классов: обработку ошибок и управление памятью.