假设我们enum
有FlagsAttribute
。
[Flags]
enum CarOptions
{
Sunroof = 1,
Spoiler = 2,
TintedWindow = 4
}
这可以很容易地使用。 现在假设这个
[Flags]
enum CarOptions
{
SunroofElectrical,
SunroofMechanical,
Spoiler,
TintedWindowBlack,
TintedWindowPurple
}
当然这在语法上是不正确的。但是,汽车不能同时拥有机械和电动天窗,也不能同时拥有黑色和紫色的TintedWindow 问题是:是否有一种机制来实现Flags枚举,它不能同时具有某些属性?
答案 0 :(得分:3)
我猜你会通过为天窗和TindedWindows使用不同的枚举来做到这一点。
答案 1 :(得分:2)
没有内置机制。标记枚举允许组合成员的任何组合。您需要在这种情况下执行手动验证,或创建不接受无效选项的模型。还有其他选择,但我选择的首选方法与此类似:
class CarOptions
{
public SunroofKind Sunroof { get; set; }
public SpoilerKind Spoiler { get; set; }
public TintedWindowKind TintedWindow { get; set; }
// Note that I split this into two enums - the kind of tinted window
// (UV-resistant option too maybe?) and color might be different.
// This is just an example of how such option composition can be done.
public TintedWindowColor TintedWindowColor { get; set; }
// In this class, you can also implement additional logic, such as
// "cannot have spoiler on diesel engine models" and whatever may be required.
}
enum SunroofKind
{
None,
Electrical,
Mechanical
}
enum SpoilerKind
{
None,
Standard
}
enum TintedWindowKind
{
None,
Standard
}
enum TintedWindowColor
{
Black,
Blue
}
如你所见,我完全摆脱了原来的枚举。在这种情况下,我没有看到任何理由使用这样的构造 - 也需要应用特定于域的组合逻辑的不同变量的组合不是标记枚举的良好候选者。选项和逻辑应该封装在一个类中(或者可能是一个结构体,具体取决于它的使用方式)。
Flag-enumerations仅对非常简单和/或特殊情况有用。
答案 2 :(得分:1)
我有两种选择:
1)不要使用enum
。使用另一种机制来设置组合中彼此冲突的选项。
2)定义无效组合并在设置标志时检查它们:
[flags]
enum CarOptions
{
SunroofElectrical = 1,
SunroofMechanical = 2,
Spoiler = 4,
TintedWindowBlack = 8,
TintedWindowPurple= 16,
// bad combos
BadSunroof = 3,
BadWindowColor = 24
}
CarOptions opt = CarOptions.SunroofElectrical | CarOptions.SunroofMechanical;
if(opt & BadSunroof)
{
}
答案 3 :(得分:1)
您可以使用一位标志来指示存在的特定功能,另一位用于指示功能的“风味”:
[Flags]
enum CarOptions
{
Sunroof = 1,
SunroofElectrical = 1,
SunroofMechanical = 3,
Spoiler = 4,
TintedWindow = 8,
TintedWindowBlack = 8,
TintedWindowPurple = 24
}
然后不可能将两种“味道”放在一起。