Для тех, кто ищет решение Java для этого, если вы используете mongojack , это очень просто:
collection.find(DBQuery.is("user", new DBRef(user.getId(), User.class)));
Где коллекция является JacksonDBCollection.
Эти [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
Добавить Mode.Write
:
Mode = Mode | Mode.Write;
Посмотрите следующее для примера, который показывает объявление и потенциальное использование:
namespace Flags
{
class Program
{
[Flags]
public enum MyFlags : short
{
Foo = 0x1,
Bar = 0x2,
Baz = 0x4
}
static void Main(string[] args)
{
MyFlags fooBar = MyFlags.Foo | MyFlags.Bar;
if ((fooBar & MyFlags.Foo) == MyFlags.Foo)
{
Console.WriteLine("Item has Foo flag set");
}
}
}
}
Я спрошенный недавно о чем-то подобном.
при использовании флагов можно добавить дополнительный метод к перечислениям для создания проверки содержавших флагов легче (см. сообщение для детали)
Это позволяет Вам делать:
[Flags]
public enum PossibleOptions : byte
{
None = 0,
OptionOne = 1,
OptionTwo = 2,
OptionThree = 4,
OptionFour = 8,
//combinations can be in the enum too
OptionOneAndTwo = OptionOne | OptionTwo,
OptionOneTwoAndThree = OptionOne | OptionTwo | OptionThree,
...
}
Тогда можно сделать:
PossibleOptions opt = PossibleOptions.OptionOneTwoAndThree
if( opt.IsSet( PossibleOptions.OptionOne ) ) {
//optionOne is one of those set
}
я нахожу это легче читать, чем большинство способов проверить включенные флаги.
@Nidonocu
Для добавления другого флага к существующему набору значений используйте ИЛИ оператор присваивания.
Mode = Mode.Read;
//Add Mode.Write
Mode |= Mode.Write;
Assert.True(((Mode & Mode.Write) == Mode.Write)
&& ((Mode & Mode.Read) == Mode.Read)));
Флаги позволяют Вам использовать bitmasking в своем перечислении. Это позволяет Вам комбинировать перечислимые величины при сохранении, которые определяются.
[Flags]
public enum DashboardItemPresentationProperties : long
{
None = 0,
HideCollapse = 1,
HideDelete = 2,
HideEdit = 4,
HideOpenInNewWindow = 8,
HideResetSource = 16,
HideMenu = 32
}
Можно также сделать это
[Flags]
public enum MyEnum
{
None = 0,
First = 1 << 0,
Second = 1 << 1,
Third = 1 << 2,
Fourth = 1 << 3
}
, я нахожу смещение бита легче, чем ввод 4,8,16,32 и так далее. Это не оказывает влияния на Ваш код, потому что это все сделано во время компиляции