Глава.15 .Перечислимые.типы.и.битовые.флаги
butes
является экземпляром перечислимого типа, основанного на типе
Int32
, где
каждый разряд соответствует какому-то атрибуту файла. В FCL тип
FileAttributes
описан следующим образом:
[Flags, Serializable]
public enum FileAttributes {
ReadOnly = 0x0001,
Hidden = 0x0002,
System = 0x0004,
Directory = 0x0010,
Archive = 0x0020,
Device = 0x0040,
Normal = 0x0080,
Temporary = 0x0100,
SparseFile = 0x0200,
ReparsePoint = 0x0400,
Compressed = 0x0800,
Offline = 0x1000,
NotContentIndexed = 0x2000,
Encrypted = 0x4000
}
Следующий фрагмент проверяет, является ли файл скрытым:
String file = Assembly.GetEntryAssembly().Location;
FileAttributes attributes = File.GetAttributes(file);
Console.WriteLine("Is {0} hidden? {1}", file, (
attributes & FileAttributes.Hidden) != 0);
ПриМеЧание
В.классе.Enum.имеется.метод.HasFlag,.определяемый.следующим.образом:
public Boolean HasFlag(Enum flag);
С.его.помощью.можно.переписать.вызов.метода.ConsoleWriteLine:
Console.WriteLine("Is {0} hidden? {1}", file,
attributes.HasFlag(FileAttributes.Hidden));
Однако.я.не.рекомендую.использовать.метод.HasFlag .Дело.в.том,.что.он.принимает.
параметры.типа.Enum,.а.значит,.передаваемые.ему.значения.должны.быть.упакованы,.
что.требует.дополнительных.затрат.памяти
А этот пример демонстрирует, как изменить файлу атрибуты «только для чте-
ния» и «скрытый»:
File.SetAttributes(file, FileAttributes.ReadOnly | FileAttributes.Hidden);
Из описания типа
FileAttributes
видно, что, как правило, при создании набора
комбинируемых друг с другом битовых флагов используют перечислимые типы.
Однако несмотря на внешнюю схожесть, перечислимые типы семантически отли-
чаются от битовых флагов. Если в первом случае мы имеем отдельные числовые
411
Битовые.флаги
значения, то во втором приходится иметь дело с набором флагов, одни из которых
установлены, а другие нет.
Определяя перечислимый тип, предназначенный для идентификации битовых
флагов, каждому идентификатору следует явно присвоить числовое значение.
Обычно в соответствующем идентификатору значении установлен лишь один бит.
Также часто приходится видеть идентификатор
None
, значение которого определено
как 0. Еще можно определить идентификаторы, представляющие часто исполь-
зуемые комбинации (см. приведенный далее символ
ReadWrite
). Настоятельно
рекомендуется применять к перечислимому типу специализированный атрибут
типа
System.FlagsAttribute
:
[Flags] // Компилятор C# допускает значение "Flags" или "FlagsAttribute"
internal enum Actions {
None = 0
Read = 0x0001,
Write = 0x0002,
ReadWrite = Actions.Read | Actions.Write,
Delete = 0x0004,
Query = 0x0008,
Sync = 0x0010
}
Для работы с перечислимым типом
Actions
можно использовать все методы,
описанные в предыдущем разделе. Хотя иногда возникает необходимость изменить
поведение ряда функций. К примеру, рассмотрим код:
Actions actions = Actions.Read | Actions.Delete; // 0x0005
Console.WriteLine(actions.ToString()); // "Read, Delete"
Метод
ToString
пытается преобразовать числовое значение в его символьный
эквивалент. Но у числового значения
0x0005
нет символьного эквивалента. Од-
нако обнаружив у типа
Actions
атрибут
[Flags]
, метод
ToString
рассматривает
числовое значение уже как набор битовых флагов. Так как биты
0x0001
и
0x0005
установлены, метод
ToString
формирует строку
"Read, Delete"
. Если в описании
типа
Actions
убрать атрибут
[Flags]
, метод вернет строку
"5"
.
В предыдущем разделе мы рассмотрели метод
ToString
и привели три способа
форматирования выходной строки:
"G"
(общий),
"D"
(десятичный) и
"X"
(шест-
надцатеричный). Форматируя экземпляр перечислимого типа с использованием
общего формата, метод сначала определяет наличие атрибута
[Flags]
. Если атрибут
не указан, отыскивается и возвращается идентификатор, соответствующий данно-
му числовому значению. Обнаружив же данный атрибут,
ToString
действует по
следующему алгоритму:
1. Получает набор числовых значений, определенных в перечислении, и сортирует
их в нисходящем порядке.
2. Для каждого значения выполняется операция конъюнкции (
AND
) с экземпляром
перечисления. В случае равенства результата числовому значению связанная
412
Do'stlaringiz bilan baham: |