Эти [Flags]
атрибут должен использоваться каждый раз, когда счетное представляет набор возможных значений, а не единственного значения. Такие наборы часто используются с побитовыми операторами, например:
var allowedColors = MyColor.Red | MyColor.Green | MyColor.Blue;
Примечание, что [Flags]
атрибут не делает , включает это отдельно - все, что это делает, позволяют хорошее представление .ToString()
метод:
enum Suits { Spades = 1, Clubs = 2, Diamonds = 4, Hearts = 8 }
[Flags] enum SuitsFlags { Spades = 1, Clubs = 2, Diamonds = 4, Hearts = 8 }
...
var str1 = (Suits.Spades | Suits.Diamonds).ToString();
// "5"
var str2 = (SuitsFlags.Spades | SuitsFlags.Diamonds).ToString();
// "Spades, Diamonds"
также важно отметить, что [Flags]
не делает , автоматически делают полномочия значений перечисления два. При исключении числовых значений перечисление не будет работать, как можно было бы ожидать в битовых операциях, потому что по умолчанию значения запускаются с 0 и инкремент.
Неправильное объявление:
[Flags]
public enum MyColors
{
Yellow, // 0
Green, // 1
Red, // 2
Blue // 3
}
значения, если объявлено этот путь, будут Желтые = 0, Green = 1, Красный = 2, Синий = 3. Это представит его бесполезный как флаги.
Вот пример корректного объявления:
[Flags]
public enum MyColors
{
Yellow = 1,
Green = 2,
Red = 4,
Blue = 8
}
Для получения отличных значений в свойстве можно сделать это:
if (myProperties.AllowedColors.HasFlag(MyColor.Yellow))
{
// Yellow is allowed...
}
или до.NET 4:
if((myProperties.AllowedColors & MyColor.Yellow) == MyColor.Yellow)
{
// Yellow is allowed...
}
if((myProperties.AllowedColors & MyColor.Green) == MyColor.Green)
{
// Green is allowed...
}
Под покрытиями
Это работает, потому что Вы использовали полномочия два в Вашем перечислении. Под покрытиями Ваши перечислимые величины похожи на это в двоичных единицах и нулях:
Yellow: 00000001
Green: 00000010
Red: 00000100
Blue: 00001000
Точно так же после установки свойства AllowedColors на Красного, Green и Синее использование двоичного битового "ИЛИ" |
оператор, AllowedColors похож на это:
myProperties.AllowedColors: 00001110
Поэтому при получении значения Вы на самом деле выполняете поразрядно И &
на значениях:
myProperties.AllowedColors: 00001110
MyColor.Green: 00000010
-----------------------
00000010 // Hey, this is the same as MyColor.Green!
Ни один = 0 значений
И относительно использования [1 116] в Вашем перечислении, заключающем в кавычки из MSDN:
[Flags]
public enum MyColors
{
None = 0,
....
}
Использование Ни один как название перечислимой константы флага, значение которой является нулем. Вы не можете использовать Ни один перечислимая константа в поразрядной операции И для тестирования на флаг, потому что результатом всегда является нуль. Однако можно выполнить логическое, не поразрядное, сравнение между числовым значением и Ни одним перечислимая константа, чтобы определить, установлены ли какие-либо биты в числовом значении.
можно найти больше информации об атрибуте флагов и его использовании в [1 117] msdn и флаги разработки в msdn
Используйте # 1 - #include во многих местах.
Никогда не используйте # 2 - никогда не объявляйте ничего более одного раза.
Редко используйте # 3 - объявляйте что-либо в .c, как будто вы никогда не собираетесь использовать его повторно.
Заголовочный файл должен содержать прототипы. Затем вы включаете его везде, где используются эти прототипы, включая файл .c, содержащий определения функций.
Кстати, DecC ++ больше не разрабатывается активно - вам следует подумать о переходе на Code :: Blocks .
Вы должны выбрать вариант 1. Или заказать myfunctions.c так, чтобы определение вызываемой функции происходило перед функцией, которая ее вызывает. Включая заголовок в файл, вы позволяете компилятору обнаруживать любое несоответствие между объявлением и определением.
Как уже было сказано, вам следует использовать первый вариант. Общее правило состоит в том, что прототипы функций находятся в файлах .h, а их реализации - в файлах .c.