Статический метод TheMachine.FireThisPerson() строился так, чтобы он мог принимать любой тип, производный от Employee, но возникает один вопрос: как метод "узнает", какой именно производный тип передается методу. Кроме того, если поступивший параметр имеет тип Employee, то как получить доступ к специфическим членам типов SalesPerson и Manager?
Язык C# обеспечивает три способа определения того, что ссылка базового класса действительно указывает на производный тип: явное приведение типа (рассмотренное выше), ключевое слово is и ключевое слово as. Ключевое слово is возвращает логическое значение, указывающее на совместимость ссылки базового класса с данным производным типом. Рассмотрим следующий обновленный метод FireThisPerson().
public class TheMachine {
public static void FireThisPerson(Employee e) {
if (e is SalesPerson){
Console.WriteLine("Имя уволенного продавца: {0}", e.GetFullName());
Console.WriteLine("{0} оформил(a) {1} операций…", e.GetFullName(), ((SalesPerson)e).NumbSales);
}
if (e is Manager){
Console.WriteLine("Имя уволенного клерка: {0}", e.GetFullName());
Console.WriteLine("{0} имел(а) (1} опцион(ов)…", e.GetFullName(), ((Manager)e).NumbOpts);
}
}
}
Здесь ключевое слово is используется для того, чтобы динамически определить тип работника. Чтобы получить доступ к свойствам NumbSales или NumbOpts, вы должны использовать явное приведение типов. Альтернативой место бы быть ис-пользование ключевого слова as для получения ссылки на производный тип (если типы при этом окажутся несовместимыми, ссылка получит значение null).
SalesPerson p = е as SalesРеrson;
if (p!= null) Console.WriteLinе("Число продаж: {0}", p.NumbSales);
Замечание. Из Главы 7 вы узнаете, что такой же подход (явное приведение типов, is и as) может использоваться при получении интерфейсных ссылок из реализующего типа.
Приведение числовых типов
В завершение нашего обзора операций приведения типов в C# заметим, что преобразование числовых типов подчиняется примерно таким же правилам. Чтобы поместить "больший" числовой тип в "меньший" (например, целое число int в byte), следует использовать явное приведение типов, которое информирует компилятор о том, что вы готовы принять возможную потерю данных.
// Если "х" больше предельного значения для byte, вероятна потеря
// данных, но из главы 9 вы узнаете о "контролируемых исключениях",
// с помощью которых можно управлять результатом.
int х = 6;
byte b = ( byte)x;
Когда вы сохраняете "меньший" числовой тип в "большем" (например, byte в int), тип для вас будет преобразован неявно и автоматически, так как здесь нет потерь данных.
// Приведение типа не требуется,
// int достаточно "велик" для хранения byte.
byte b = 30; int x = b;
В C# 2005 вводится новый модификатор типа partial, который позволяет определять C#-тип в нескольких файлах *.cs. Предыдущие версии языка C# требовали, чтобы весь программный код определения типа содержался в пределах одного файла *.cs. С учетом того, что C#-класс производственного уровня может содержать сотни строк программного кода, соответствующий файл может оказаться достаточно объемным.
В таких случаях было бы хорошо иметь возможность разделить реализацию типа на несколько файлов, чтобы отделить программный код, который в некотором смысле более важен, от других элементов. Например, используя для класса модификатор partial, можно поместить все открытые члены в файл с именем MyТуре_Public.cs, а приватные поля данных и вспомогательные функции – в файл MyType_Private.cs.
// MyClass_Public.cs
namespace PartialTypes {
public partialclass MyClass {
// Конструкторы.
public MyClass() {}
// Открытые члены.
public void MemberA() {}
public void MemberB() {}
}
}
// MyClass_Private.cs
namespace PartialTypes {
public partialclass MyClass {
// Приватные поля данных.
private string someStringData;
// Приватные вспомогательные члены.
public static void SomeStaticHelper(){}
}
}
Это, в частности, упростит задачу изучения открытого интерфейса типа для новых членов команды разработчиков. Вместо изучения единого (и большого) файла C# с целью поиска соответствующих членов, разработчики получают возможность рассмотреть только открытые члены. Конечно, после компиляции этих файлов с помощью csc.exe в результате все равно получается единый унифицированный тип (рис. 4.14).
Читать дальше