Struct MyPoint {
public int x, у;
}
Предположим, что вы посылаете переменную MyPoint новому методу с именем UseBoxedMyPoint().
static void Main(string[] args) {
…
MyPoint p;
p.x = 10;
p.y = 20;
UseBoxedMyPoint(p);
}
При попытке получить доступ к полю данных MyPoint возникнет ошибка компиляции, поскольку метод предполагает, что вы действуете на строго типизованный System.Object.
static void UseBoxedMyPoint(object o) {
// Ошибка! System.Object не имеет членов-переменных
// с именами 'х' и 'у'.
Console.WriteLine ("{0}, {1}", о.х, о.у);
}
Чтобы получить доступ к полю данных MyPoint, вы должны сначала восстановить параметр из объектного образа. Сначала можно использовать ключевое слово C# is для проверки того, что этот параметр на самом деле является переменной MyPoint. Ключевое слово is рассматривается в главе 4, здесь мы только предлагаем пример его использования.
static void UseBoxedMyPoint(object о) {
if (о isMyPoint) {
MyPoint p = (MyPoint)o;
Console.WriteLine ("{0}, {1}", p.x, p.y);
} else Console.WriteLine("Вы прислали не MyPoint.");
}
Исходный код.Проект Boxing размещен в подкаталоге, соответствующем главе 3.
Вдобавок к структурам в .NET имеется еще один тип из категории характеризуемых значением – это перечни. При создании программы часто бывает удобно создать набор символьных имен для представления некоторых числовых значений. Например, при создании системы учета оплаты труда работников предприятия вы предпочтете использовать константы Manager (менеджер), Grunt (рабочий), Contractor (подрядчик) и VP (вице-президент) вместо простых числовых значений {0, 1, 2, 3}. Именно по этой причине в C# поддерживаются пользовательские перечни. Например, вот перечень EmpType.
// Пользовательский перечень.
enum EmpType {
Manager, // = 0
Grunt, // = 1
Contractor, // = 2
VP // = 3
}
Перечень EmpType определяет четыре именованные константы, соответствующие конкретным числовым значениям. В C# схема нумерации по умолчанию предполагает начало с нулевого элемента (0) и нумерацию последующих элементов по правилам арифметической прогрессии n + 1. При необходимости вы имеете возможность изменить такое поведение на более удобное.
// начало нумерации со значения 102.
enum EmpType {
Manager = 102,
Grunt, // = 103
Contractor, // =104
VP // = 105
}
Перечни не обязаны следовать строгому последовательному порядку нумерации элементов. Если (по некоторой причине) вы сочтете разумным создать EmpType так, как показано ниже, компилятор примет это без возражений.
// Элементы перечня не обязаны следовать в строгой последовательности!
enum EmpType {
Manager = 10,
Grunt = 1,
Contractor = 100,
VP = 9
}
Тип, используемый для каждого элемента в перечне, по умолчанию отображается в System.Int32. Такое поведение при необходимости тоже можно изменить. Например, если вы хотите, чтобы соответствующее хранимое значение EmpTyре было byte, а не int, вы должны написать следующее.
// Теперь EmpType отображается в byte.
enum EmpType: byte{
Manager = 30,
Grunt = 1,
Contractor = 100,
VP = 9
}
Замечание.Перечни в C# могут определяться в унифицированной форме для любого из числовых типов (byte, sbyte, short, ushort, int, uint, long или ulong). Это может быть полезно при создании программ для устройств с малыми объемами памяти, таких как КПК или сотовые телефоны, совместимые с .NET.
Установив диапазон и тип хранения для перечня, вы можете использовать его вместо так называемых "магических чисел". Предположим, что у вас есть класс, определяющий статическую функцию с единственным параметром EmpType.
static void AskForBonus (EmpType e){
switch(e) {
case EmpType.Contractor:
Console.WriteLine("Вам заплатили достаточно…");
break;
case EmpType.Grunt:
Console.WriteLine("Вы должны кирпичи укладывать…");
break;
case EmpType.Manager:
Console.WriteLine("Лучше скажите, что там с опционами!");
break;
case EmpType.VP:
Console.WriteLine("ХОРОШО, сэр!");
break;
default:
break;
}
}
Этот метод можно вызвать так.
static void Main(string[] args) {
// Создание типа contractor.
EmpType fred;
fred = EmpType.Contractor;
Читать дальше