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

Сейчас мы рассмотрим один из самых важных аспектов типов — приведение. Допустим, существует базовый класс под названием Employee и производный класс ContractEmployee. Следующий код будет работать, поскольку всегда подразумевается восходящее приведение (upcast) производного класса к его базовому классу:



class Employee { }

class ContractEmployee : Employee { }

class CastExamplel

{

public static void Main () {

Employee e = new ContractEmployeeQ; } }

А вот такой код недопустим, так как компилятор не предоставляет неявное нисходящее приведение (downcast).


class Employee { }

class ContractEmployee : Employee { }

class CastExample2 {

public static void Main ()

{

ContractEmployee ce = new EmployeeQ; // He будет

// компилироваться.

} }



Причина различного поведения этих фрагментов кода, описанная в главе 1, связана с понятием заменяемости (substitutability). Правила заменяемости гласят: производный класс может быть использован вместо своего базового класса. Поэтому объект типа ContractEmployee всегда можно использовать вместо объекта Employee. Потому и компилируется код первого примера.

Однако вы не сможете выполнить нисходящее приведение объекта типа Employee к объекту типа ContractEmployee, поскольку нет гарантии, что этот объект поддерживает интерфейс, определенный классом ContractEmployee. Поэтому в случае нисходящего приведения используется явное приведение:


class Employee { }

class ContractEmployee : Employee { }

class CastExampleS {

public static void Main ()

{

// Нисходящее приведение не сработает.

ContractEmployee ce = (ContractEmployee)new Employee(); } }

А давайте обманем CTS путем явного приведения базового класса к производному:


class Employee { }

class ContractEmployee : Employee { }

class CastExample4 {

public static void Main ()

<

Employee e = new EmployeeO; ContractEmployee с = (ContractEmployee)e; } }

Эта программа компилируется, но генерирует исключение периода выполнения. Здесь важны два момента. Во-первых, ошибка периода компиляции не возникает, так как е на самом деле может быть объектом ContractEmployee, приведенным к базовому классу. Поэтому истинная природа объекта, приведенного к базовому классу, не может быть распознана до периода выполнения. Во-вторых, CLR определяет типы объектов в период выполнения. Распознав неверное приведение, CLR генерирует исключение System.InvalidCastException.

Есть еще один способ приведения объектов — ключевое слово «5. Преимущество использования as вместо собственно приведения в том, что в случае неверного приведения вам не придется беспокоиться о возникающем исключении. Вместо этого вы получите null, например:

using System;

class Employee { >

class ContractEmployee : Employee { }

class CastExampleS {

public static void Main ()

{

Employee e = new EmployeeO;

Console.WriteLine(“e = {0}”,

e == null ? “null” : e.ToStringO);

ContractEmployee с = e as ContractEmployee; Console.WriteLine(“c = {0}”,

с == null ? “null” : e.ToStringO); > }

Запустив этот пример, вы увидите такой результат:

c:>CastExample5 e = Employee с = null

Способность сравнивать объект с null означает, что вы ничем не рискуете, используя пустые объекты. Фактически, если в приведенном выше примере вызвать метод System.Object для объекта с, то CTS сгенерирует исключение System.NullReferenceException.

Пространства имен

Пространства имен (namespaces) используются в С#-приложениях для определения области видимости. Объявив пространство имен, разработчик может дать С#-приложению иерархическую структуру, основанную на семантически связанных группах типов и других (вложенных) пространствах имен. В формировании одного пространства имен могут участвовать несколько файлов исходного кода. Это обстоятельство позволяет при компоновке единого пространства имен из нескольких классов определять каждый класс в собственном файле исходного кода. Программист, использующий созданные вами классы, получит доступ ко всем классам в пространстве имен через ключевое слово using.

ПРИМЕЧАНИЕ Там, где это возможно, рекомендуется использовать имя компании в качестве корня пространства имен, чтобы гарантировать его уникальность.

Понравилась статья? Поделиться с друзьями:
Добавить комментарий

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!: