Я прошу прощения за заголовок этого вопроса, но я не мог придумать лучшего способа описать то, что я пытаюсь достичь ..
Я хочу создать Enum с использованием атрибута Flags, чтобы побитовые значения enum создавали некоторую схему наследования.
Пример: скажем, у нас есть битовое поле enum of food:
[Flags]
enum Foods
{
// Top Level foods
Meat,
Fruit,
Vegetables,
Dairy,
Grain,
BenJerrysOatmealCookieChunk, // ;)
// sub-Meat
Chicken,
Beef,
Fish,
// sub-Fruit
Apple,
Banana,
// sub-Vegetables
Spinach,
Broccoli,
// sub-Dairy
Cheese,
Milk,
// sub-Grain
Bread,
Pasta,
Rice,
// sub-Beef
Tritip,
Hamburger,
// sub-Fish
Salmon,
Halibut,
}
Обратите внимание, что перечисление содержит подкатегории продуктов питания, а также подкатегории. В моем реальном сценарии у меня есть неизвестное количество категорий верхнего уровня и неизвестное количество категорий подуровня (включая неизвестный уровень под-под-под-под-n-категорий)
Я бы хотел установить значения битов перечисления так, чтобы подкатегории (и под-под-подкатегории) «наследовали» значение бита своего непосредственного родителя.
Я хочу, чтобы клиентский установщик свойства Foods не устанавливал явно все флаги для определенного продукта. Другими словами, я не хочу, чтобы клиентский установщик делал что-то вроде:
myClass.Foods = Foods.Tritip | Foods.Beef | Foods.Meat;
Я пытаюсь создать конструкцию, чтобы установщик клиента просто устанавливал один флаг, и все родители этого флага были неявными в дочернем флаге.
Итак, если установщик клиента сделал это:
myClass.Foods = Foods.Tritip;
Мы сможем успешно выполнить следующие условия:
if((myClass.Foods & Foods.Meat) == Foods.Meat)
Console.WriteLine("I am meat");
if((myClass.Foods & Foods.Beef) == Foods.Beef)
Console.WriteLine("I am beef");
if((myClass.Foods & Foods.Tritip) == Foods.Tritip)
Console.WriteLine("I am tritip");
if((myClass.Foods & Foods.Meat) == Foods.Meat)
Console.WriteLine("I am meat");
if((myClass.Foods & Foods.Rice) != Foods.Rice)
Console.WriteLine("I am definitely not rice!");
Что меня смущает в этой проблеме, так это то, какие битовые значения используются для каждого элемента питания в перечислении. Я изначально начал с:
[Flags]
enum Foods
{
// Top Level foods
Meat = 0x1,
Fruit = 0x2,
Vegetables = 0x4,
Dairy = 0x8,
Grain = 0x10,
BenJerrysOatmealCookieChunk = 0x20, // ;)
...and so on.
}
.. но так как я не знаю, сколько будет уровней (список enum будет расти со временем) .. Я не знаю, как создавать свои битовые значения, чтобы они учитывали рост.
Кто-нибудь пытался сделать это раньше? Если да, какова была ваша бизнес-логика для ваших битовых значений?
У меня подлое чувство, что этот Вопрос будет нуждаться в награде;)