2011-01-19 2 views
5

Я нашел этот фрагмент кода на SO (жаль, что я не имею ссылку на вопрос/ответ комбо)Как этот оператор C# работает в этом фрагменте кода?

bool isDir = (File.GetAttributes(source) & FileAttributes.Directory) == FileAttributes.Directory; 

Это меня смущает, потому что FileAttributes.Directory на обеих сторонах ==.

Что делает & в этом случае? Я не уверен, как читать эту строку кода. Я пытаюсь оценить, является ли строка пути файлом или каталогом.

ответ

5

Используется бит-маска, чтобы проверить, установлен ли один бит (FileAttributes.Directory).

Значения перечисления являются степенями двух, соответствующими отдельным битам.

ReadOnly = 1, 
    Hidden = 2, 
    System = 4, 
    Directory = 16, 
    Archive = 32, 
    Device = 64, 

Если ReadOnly и каталог устанавливаются затем FileAttributes равно 17. Расчет выглядит следующим образом в двоичном:

File.GetAttributes(source) = 00001001 
FileAttributes.Directory = 00001000 & 
------------------------------------- 
          00001000 

Если бит Справочник был не набор вы получите ноль вместо :

File.GetAttributes(source) = 00000001 
FileAttributes.Directory = 00001000 & 
------------------------------------- 
          00000000 

немного более краткий способ записать выражение, которое дает тот же эффект, чтобы проверить на ноль:

bool isDir = (File.GetAttributes(source) & FileAttributes.Directory) != 0; 
+0

Я не уверен, как C++ обрабатывает логические значения, но ANSI C также позволит немного короче: bool isDir = (File.GetAttributes (source) & FileAttributes.Directory); – oosterwal

5

его выполнение побитовая операция И. Атрибуты хранятся как битовые флаги, поэтому они и эти флаги вместе с AttributeFlags.Directory, чтобы увидеть, является ли один из атрибутов .Directory.

Хороший пример битовых флагов здесь: http://weblogs.asp.net/wim/archive/2004/04/07/109095.aspx

[Flags] 
public enum FileAttributes 
{ 
    Archive,  // 0000 
    Compressed,  // 0001 
    Device,   // 0010 
    Directory,  // 0100 
    Encrypted,  // 1000 
    ... 
} 

Тогда:

File.GetAttributes(source): 1101 
FileAttributes.Directory: 0100 
(Logical AND):    0100 

0100 такая же, как флаг директории, так что мы теперь знаем, что этот флаг в выбранных флагов перечисления.

1

& В данном случае это поразрядный оператор and.

2

Это logical & operator. В этом конкретном примере он проверяет, имеет ли значение перечисление FileAttributes значение Directory, проверяя, является ли строка, указанная переменной source, каталогом.

0

Это побитовый оператор AND.
http://en.wikipedia.org/wiki/Bitwise_operation

codesnippet выполняет побитовое И между двумя переменными, а затем сравнивает значение другой переменной, помещая результат в BOOL.

0

Побитовое устройство AND. FileAttributes - Перечисление флагов. Это означает, что каждый бит в числовом значении этого перечисления описывает некоторое логическое свойство этого файла, и их можно комбинировать.

1

Выполняет побитовое испытание флажком - File.GetAttributes(source) может вернуть номер флагов (в разных битах) с указанием различных свойств. & ограничивает 1 s до только те, которые присутствуют в FileAttributes.Directory (я бы ожидал, что это будет один бит). Как это происходит, это 16, то есть (двоичный) ..0001000

если source имеет ReadOnly (= 1), Hidden (= 2) и Directory (= 16) было бы:

...0001011 

мы & с 16

...0001000 

оставляя

...0001000 

отсюда справочный тест проходит.

Если вместо того, чтобы источник имеет System (= 4) и ReadOnly (= 1) (а не каталог) будет:

...0000101 

мы & с 16

...0001000 

оставляя

...0000000 

отсюда справочный тест не работает.

В качестве побочного примечания; a == в таком тесте проверяет, что все были установлены необходимые флаги (если несколько бит были во втором операнде). Другим распространенным тестом является != 0, который проверяет, присутствовали ли любые битов.

0

Проверяется, установлен ли флаг FileAttributes.Directory в перечислении, возвращаемом File.GetAttributes. Вы можете узнать больше о том, как использовать перечисления флагов в this entry on MSDN.

Я пытаюсь оценить, является ли строка пути файлом или каталогом.

Я предпочел бы использовать один из методов в System.IO, как Directory.Exists:

if (Directory.Exists(path)) 
{ 
    // it's a directory 
} 
else if (File.Exists(path)) 
{ 
    // it's a file 
} 
else 
{ 
    // doesn't exist 
} 
0

GetAttributes возвращает значение флага, где каждый бит представляет собой другую булеву состояние. Этот код использует побитовый оператор &, чтобы включить флаг Directory, в дополнение к любым другим флагам, возвращаемым GetAttributes.

Это, похоже, было чрезмерно сложным. Это эквивалентно запись:

bool isDir = File.GetAttributes(source).HasFlag(FileAttributes.Directory); 

Или, чтобы проверить исключительно для атрибута каталога:

Метод HasFlag() в настоящее время немного медленно, поэтому побитовая альтернатива быстрее и использует меньше Ресурсы. HasFlag хорош для быстрого и легкого ответа на то, включен или выключен нужный бит во флагах, без каких-либо знаний о битовых значениях или двоичных данных в целом.