Существует раздел приблизительно пиксельное управление в документации W3C.
Вот пример о том, как инвертировать изображение :
var context = document.getElementById('myCanvas').getContext('2d');
// Get the CanvasPixelArray from the given coordinates and dimensions.
var imgd = context.getImageData(x, y, width, height);
var pix = imgd.data;
// Loop over each pixel and invert the color.
for (var i = 0, n = pix.length; i < n; i += 4) {
pix[i ] = 255 - pix[i ]; // red
pix[i+1] = 255 - pix[i+1]; // green
pix[i+2] = 255 - pix[i+2]; // blue
// i+3 is alpha (the fourth element)
}
// Draw the ImageData at the given (x,y) coordinates.
context.putImageData(imgd, x, y);
Традиционно это был способ уменьшить использование памяти. Так что да, в C # он довольно устарел: -)
Как метод программирования, он может быть устаревшим в сегодняшних системах, и вы вполне можете использовать массив bool, но ...
Это быстро сравнивает значения, хранящиеся в виде битовой маски. Используйте логические операторы И и ИЛИ и сравните полученные 2 целых числа.
Он использует значительно меньше памяти. Помещение всех 4 значений вашего примера в битовую маску потребует полбайта. При использовании массива bool, скорее всего, для объекта массива будет использовано несколько байтов плюс длинное слово для каждого bool. Если вам нужно сохранить миллион значений, вы точно поймете, почему версия с битовой маской лучше.
Этим проще управлять, вам нужно иметь дело только с одним целочисленным значением, тогда как массив булевых значений будет хранить совершенно иначе в, скажем, базе данных.
И из-за структуры памяти намного быстрее во всех аспектах, чем массив. Это почти так же быстро, как при использовании одного 32-битного целого числа. Все мы знаем, что это настолько быстро, насколько это возможно для операций с данными.
Простая установка нескольких флагов в любом порядке.
Легко сохранить и получить в базу данных серию 0101011.
Среди прочего, легче добавить новые значения битов в битовое поле, чем добавлять новые логические значения в класс. Также проще скопировать битовое поле из одного экземпляра в другой, чем серию логических значений.
Это также может сделать методы более понятными. Представьте себе метод с 10 булевыми значениями и 1 битовой маской.
Фактически, он может иметь лучшую производительность, в основном, если ваше перечисление является производным от байта. В этом крайнем случае каждое значение перечисления будет представлено байтом, содержащим все комбинации до 256. Наличие такого количества возможных комбинаций с логическими значениями привело бы к 256 байтам.
Но даже тогда я не думаю, что это настоящая причина. Причина, по которой я предпочитаю их, заключается в том, что C # дает мне возможность обрабатывать эти перечисления. Я могу добавить несколько значений с помощью одного выражения. Я тоже могу их удалить. Я даже могу сравнить сразу несколько значений с одним выражением с помощью перечисления. С логическими значениями код может стать, скажем, более подробным.
Я бы посоветовал никогда не использовать флаги перечисления, если вы не имеете дело с некоторыми довольно серьезными ограничениями памяти (маловероятно). Вы всегда должны писать код, оптимизированный для обслуживания.
Наличие нескольких логических свойств упрощает чтение и понимание кода, изменение значений и предоставление комментариев Intellisense, не говоря уже о снижении вероятности ошибок. При необходимости вы всегда можете использовать поле флага перечисления внутри, просто убедитесь, что вы предоставляете установку / получение значений с помощью логических свойств.
У Раймонда Чена есть сообщение в блоге на эту тему .
Конечно, битовые поля экономят память данных, но вы должны уравновесить это с стоимость кода, возможность отладки и уменьшенная многопоточность.
Как говорили другие, его время в значительной степени прошло. Заманчиво продолжать это делать, потому что возиться с битами - это весело и круто, но это уже не более эффективно, у него есть серьезные недостатки с точки зрения обслуживания, он плохо работает с базами данных, и если вы не работаете в встроенный мир, у вас достаточно памяти.
С точки зрения модели домена, он просто лучше моделирует реальность в некоторых ситуациях. Если у вас есть три логических значения, таких как AccountIsInDefault и IsPreferredCustomer и RequiresSalesTaxState, то нет смысла добавлять их в одно оформленное перечисление Flags, поскольку они не являются тремя разными значениями для одного и того же элемента модели домена.
Но если у вас есть набор логических значений, например:
[Flags] enum AccountStatus {AccountIsInDefault=1,
AccountOverdue=2 and AccountFrozen=4}
или
[Flags] enum CargoState {ExceedsWeightLimit=1,
ContainsDangerousCargo=2, IsFlammableCargo=4,
ContainsRadioactive=8}
Тогда полезно иметь возможность сохранить общее состояние Аккаунта (или груза) в ОДНОЙ переменной ...
В большинстве случаев это не стоит компромисса с точки зрения обслуживания. Однако бывают случаи, когда это полезно:
Конечно, были дополнительные затраты в коде, который обращался к этой информации и манипулировал ею, но в любом случае это выполнялось функциями, так что однажды вы определили аксессоры, это не менее удобно в обслуживании, чем использование логических значений.
Это для скорости и эффективности. По сути, все, с чем вы работаете, - это один тип int.
if ((flags & AnchorStyles.Top) == AnchorStyles.Top)
{
//Do stuff
}