Dier_Sergio_Great
@Dier_Sergio_Great
Увлеченный человек

Как правильно сравнивать ENUM на C#?

Помогите плииз.
Я уже обрыл и яндекс, и stackoverflow и прочее.
как правильно делать проверки ENUM ?

DirectoryInfo dir = new DirectoryInfo("D:\\");
if (dir.Attributes == (FileAttributes.Hidden & FileAttributes.Offline)) 
{
        return;
}

Суть в том что когда я делаю поиск содержимого папки на под папки, там попадаются папки с именем D:\$RECYCLE.BIN
А мне эти папки не нужны, но они вызывают ошибки, так же надо отсечь скрытые папки и системные на подобии Windows.
В общем при выполнении этого кода, он не срабатывает на скрытые папки.
Как правильно сравнивать ENUM?

Хочется понять значение операторов & и | в данном сравнении, что они делают.

Странное дело. Почему то все мои логические диски как папки имеют атрибуты
directory.Attributes = Hidden | System | Directory | Archive

Как диск D: может иметь атрибут Hidden?
Не удивительно что у меня код не работает.
Таким образом я не могу отделить папку D:\$RECYCLE.BIN от папки D:\. Они оба имеют атрибут скрытой.
  • Вопрос задан
  • 582 просмотра
Решения вопроса 3
@none7
FileAttributes не является Enum в привычном смысле. Это битовая маска, то есть число в котором определенные биты имеют определенные значения. Пример откровенно говоря неправильный, так как в ожидаемые директории будет иметь ещё и атрибут Directory, как минимум. Если нужно найти все файлы имеющие один из атрибутов, то код должен выглядеть так
if(dir.Attributes & (FileAttributes.Hidden | FileAttributes.Offline) != 0)

Здесь мы складываем биты двух атрибутов и если любой из них не будет равен 0, то условие сработает.
Ответ написан
freeExec
@freeExec
Участник OpenStreetMap
Тут надо шарить в битовом представлении чисел и логических операциях.
В данном случае FileAttributes представляет собой набор описывающий каждый бит, как признак (атрибут у enum [Flags]).
Поэтому если мы хотим объединить признаки, например как вы (скрытый и оффлайн) то нужно использовать логическое сложение OR он же |.
А вот чтобы проверить, что в Attributes включены те биты, что нам нужны используют логическое умножение AND он же &. В результате останутся только биты, которые были в обоих числах. То есть по сути нам нужно сравнить результат с нашей проверкой.

var hideAndOffline = FileAttributes.Hidden | FileAttributes.Offline;
if ((dir.Attributes & hideAndOffline) == hideAndOffline)


Ну вот например у моей паки корзины атрибут в числовом выражении равен 0x16, оно же в бинарном b10110
Мы видим что активно три бита, первый, второй и четвертый, что соответствует Hidden(0x2) + System(0x4) + Directory(0x10) = 0x16. Забавно, что в структуре FileAttributes не описан третий бит.
Ответ написан
var hiddenAndOffline = FileAttributes.Hidden | File.Attributes.Offline;
if((dir.Attributes & hiddenAndOffline) == hiddenAndOffline)
{
  /* Файл скрыт и offline*/
}
if((dir.Attributes & hiddenAndOffline) != 0)
{
 /* Файл скрыт или offline или всё вместе */
}
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
Dier_Sergio_Great
@Dier_Sergio_Great Автор вопроса
Увлеченный человек
Спасибо всем участникам. Кроме вопроса, Вы помогли раскрыть эту тему полностью. Надеюсь это будет полезно ищущим. Собственно я вопрос этот специально писал, чтобы его можно было легко найти через поиск.

Если интересно.
То прога простая, консольная, благодаря Вам ее написал. Показывает список папок и файлов пути которых больше чем 250 символов. Так как злой проводник Windows имеет ограничение для копирования файлов в 250 символов.
Нет возможности делать резервные копии. При больших объемах резервного копирования всегда найдутся 1000 файлов которые выдадут ошибку при копировании.
Надеюсь прога будет полезной.
https://disk.yandex.ru/d/q6YMB4pSRc3Kgw
620ead748c90b952359871.png
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы