C#中的否定标志

时间:2011-04-04 10:13:44

标签: c# enums flags

嘿,有没有办法在C#中存储负面标志?例如,我有以下标志枚举代表一些样式:

[Flags]
public enum Styles
{
    Default = 0,
    Bold = 1,
    Italic = 2
}

现在我有多个对象,可以应用这些样式,然后将所有相关组合起来(即其他对象可以继承一些先前设置的样式)。除此之外,我想定义负面标志,基本上撤消继承的样式。因此,如果样式先前设置为Styles.Bold | Styles.Italic并且对象继承了该样式但设置了负Styles.Bold标记,那么结果应该只是Styles.Italic

是否有任何机制已经这样做了?我现在基本上有两种方式:首先是定义NotXY枚举值,然后以某种方式解析,以便在设置时消除XY值。

另一个是简单地定义两个字段,正标志和负标志,其中负标志是在额外字段中专门定义的,我只需执行positiveFlags ^ negativeFlags即可得到结果标志。

编辑:

如果不清楚,我需要存储每个中间对象的样式。所以它可能是这样的:

object1: Default
object2: Bold
object3: -Bold Italic

如果object3也继承了1和2的值,那么最终结果应该只是Italic

回应Kieren Johnstone的问题的另一个例子,根据我在评论中的陈述,负面价值只适用于当前的水平:

1: Bold
2: -Bold -Italic
3: Italic

2从先前的对象中删除了Bold和Italic,但之后不应该再应用(但值应为正值),因此最终值将再次为Italic

4 个答案:

答案 0 :(得分:8)

负面总是优先吗?如果您从NotBold开始,然后添加Bold

,该怎么办?

如果在出现时总是被负数覆盖,我会建议两个字段:

private Styles baseStyles;
private Styles overrideDisableStyles;
public Styles ResultsStyles { return baseStyles & ~overrideDisableStyles; }

或者您可以创建一个包含SetStyleUnsetStyle的辅助类:

public void SetStyle(Styles styles)
{
    this.styles |= styles;
}

public void UnsetStyle(Styles styles)
{
    this.styles &= ~styles;
}

作为参考,positiveFlags ^ negativeFlags将不起作用。考虑未设置BoldNotBoldBold的情况。结果将是NotBold,即使唯一指定的标记是Style

最后,如果您正在做任何商业,深入,比您在此处描述的更复杂并且希望具有可扩展/可扩展样式继承的任何内容,您应该使用对象图/类层次结构正确设计它 - 从定义开始具有一个或多个父对象的Style类。每个Properties都可以有一组属性名称/值对,它们覆盖父项中的任何内容 - 可能有一个Evaluate集合返回这些覆盖,一个{{1}}方法从根对象并导航到相关样式,构建一个结果属性列表供您使用。

希望有所帮助。

答案 1 :(得分:2)

我建议采用第二种方法。这对我来说似乎更加明显和简单。

答案 2 :(得分:1)

  

另一个是简单地定义两个字段,正标志和负标志,其中负标志是在额外字段中专门定义的,我只需执行positiveFlags ^ negativeFlags即可得到结果标志。

这对我来说似乎最自然(除了表达shoud read positiveFlags & ~negativeFlags)。此外,它导致了一种应用继承样式的简单方法。如果我们重写你的例子

1: Bold
2: -Bold -Italic
3: Italic 

as(没有具体的语法......)

1: pos:{ Bold }   neg:{ none }
2: pos:{ none }   neg:{ Bold Italic }
3: pos:{ Italic } neg:{ none }

然后使用(prevLevelStyle | pos) & ~neg的继承计算有效样式,结果为:

1: ({ none } | { Bold })   & ~{ none }        = { Bold }
2: ({ Bold } | { none })   & ~{ Bold Italic } = { none }
3: ({ none } | { Italic }) & ~{ none }        = { Italic }

根据需要。

答案 3 :(得分:0)

如果我没有弄错,你不一定要定义负面标志,而是使用“正面”标志来取消它们。

例如,此代码可用于取消设置粗体标记

Styles styles = Styles.Bold | Styles.Italic;
styles = styles ^ Styles.Bold;