static void CastingExamples

{

  // Manager "является" System.Object, поэтому в переменной

  // типа object можно сохранять ссылку на Manager.

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

  // Manager тоже "является" Employee.

  Employee moonUnit = new Manager("MoonUnit Zappa", 2, 3001, 20000,

                                  "101-11-1321", 1);

  // PtSalesPerson "является" SalesPerson.

  SalesPerson jill = new PtSalesPerson("Jill", 834, 3002, 100000,

                                       "111-12-1119", 90);

}

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

static void GivePromotion(Employee emp)

{

  // Повысить зарплату...

  // Предоставить место на парковке компании...

  Console.WriteLine("{0} was promoted!", emp.Name);

}

Из-за того, что данный метод принимает единственный параметр типа Employee, в сущности, ему можно передавать объект любого унаследованного от Employee класса, учитывая наличие отношения "является":

static void CastingExamples

{

  // Manager "является" System.Object, поэтому в переменной

  // типа object можно сохранять ссылку на Manager.

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

  // Manager также "является" Employee.

  Employee moonUnit = new Manager("MoonUnit Zappa", 2, 3001, 20000,

                                  "101-11-1321", 1);

  GivePromotion(moonUnit);

  // PtSalesPerson "является" SalesPerson.

  SalesPerson jill = new PtSalesPerson("Jill", 834, 3002, 100000,

                                       "111-12-1119", 90);

  GivePromotion(jill);

}

Предыдущий код компилируется благодаря неявному приведению от типа базового класса (Employee) к производному классу. Но что, если вы хотите также вызвать метод GivePromotion с объектом frank (хранящимся в общей ссылке System.Object)? Если вы передадите объект frank методу GivePromotion напрямую, то получите ошибку на этапе компиляции:

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

// Ошибка!

GivePromotion(frank);

Проблема в том, что вы пытаетесь передать переменную, которая объявлена как принадлежащая не к типу Employee, а к более общему типу System.Object. Учитывая, что в цепочке наследования он находится выше, чем Employee, компилятор не разрешит неявное приведение, стараясь сохранить ваш код насколько возможно безопасным в отношении типов.

Несмотря на то что сами вы можете выяснить, что ссылка object указывает в памяти на объект совместимого с Employee класса, компилятор сделать подобное не в состоянии, поскольку это не будет известно вплоть до времени выполнения. Чтобы удовлетворить компилятор, понадобится применить явное приведение, которое и является вторым правилом: в таких случаях вы можете явно приводить "вниз", используя операцию приведения С#. Базовый шаблон, которому нужно следовать при выполнении явного приведения, выглядит так:

(класс_к_которому_нужно_привести) существующая_ссылка

Таким образом, чтобы передать переменную типа object методу GivePromotion, потребуется написать следующий код:

// Правильно!

GivePromotion((Manager)frank);

<p id="AutBody_Root281">Использование ключевого слова as</p>
Перейти на страницу:

Похожие книги