枚举的联盟成员在C#

问题描述:

让我们说,我有一个enum BasicType,其定义如下:枚举的联盟成员在C#

public enum ObjectType{ 
     A = 1, 
     B = 2, 
     C = 3, 
    } 

的BasicType标识执行任何Object的三元分类。随后,我意识到对象需要以类似的方式进行处理相比,Ç,所以限定的另一enum ObjectGroupType如下:

public enum ObjectGroupType 
{ 
    AB = 1, 
    C = 2, 
} 

随着新的枚举,我我能够将多种已知类型的对象作为一个对象。因此,当我收到各种类型的对象流时,我实际上会识别它们是属于AB还是C类型。有没有一个优雅的解决方法呢?举例来说,我将能够在ObjectGroupType指定为A和B相同的枚举值:?

编辑1:我无法找到相似的问题here

编辑2 :感谢Maurice对你的建设性意见 - 从你的回答中得到线索,我想出了这个重新定义的ObjectGroupType

public enum ObjectGroupType 
{ 
    AB = ObjectType.A | ObjectType.B 
    C = 2, 
} 

这是有效的吗?

本质上,当我处理AB类型的对象流时,我想确定类型A或类型B的对象。这是非常相似的分级两级决策树:

object 
    / \ 
AB  C 
/\ 
A B 
+0

你有,你想如何使用这个'enum'工作的例子吗? – Jace

+3

你为什么要标记java? – ganesshkumar

+1

这看起来像是一个副本https://stackoverflow.com/questions/8043027/non-unique-enum-values – Olathe

您可以使用一个int,而不是一个枚举,结合时不重叠的使用价值即(即值,其二进制表示只有一位上),然后在参数的对象类型进行屏蔽操作,以确定它是否是AB:

class SomeClass 
{ 
    public static class ObjectType 
    { 
     public const int A = 1; 
     public const int B = 2; 
     public const int C = 4; 
     public const int D = 8; 
    } 

    public int MyType; 
    public string Title; 
    static void Main(string[] args) 
    { 
     List<SomeClass> list = new List<SomeClass>() 
     { 
      new SomeClass() {Title ="I am of type A", MyType = ObjectType.A } 
      ,new SomeClass() {Title ="I am of type B", MyType = ObjectType.B } 
      ,new SomeClass() {Title ="I am of type AB", MyType = ObjectType.A | ObjectType.B } 
     }; 

     list.ForEach(p => { if (p.MyType == (ObjectType.A | ObjectType.B)) Console.WriteLine(p.Title); }); 
    } 
} 

这种方法的缺点是失去对象类型的强类型,即你可以指定任何价值不只是那些你在ObjectType中定义。

如果我误读了你的意图,我很抱歉,但它几乎听起来像你希望允许多种不同的枚举类型在你的代码中基于枚举值起作用。好处是你可以通过按位运算和枚举来完成。

由于看起来像这样的枚举:

[Flags] 
enum ObjectType 
{ 
    A = 1, 
    B = 2, 
    C = 4, 
    D = 8 
} 

你可以设置一个比较值是按位或几个值:

var allowedValues = ObjectType.A | ObjectType.C; 

这工作,因为在枚举行为的值像封面下的位域。

当你运行你的代码时,你对allowedValues变量和测试变量进行按位AND操作,看它是否与你的测试变量相匹配。如果是的话,那么它就是你想要的值之一:

if ((test & allowed) == test) ... 

以下是使用枚举上面显示了它是如何工作的工作示例。

void Main() 
{ 
    var allowed = ObjectType.A | ObjectType.C; 

    var values = new int [] { 1, 2, 4, 8 }; 

    foreach (var i in values) 
    { 
     var test = (ObjectType)i; 

     if ((test & allowed) == test) 
     { 
      Console.WriteLine("Found a match: {0}", test); 
     } 
     else 
     { 
      Console.WriteLine("No match: {0}", test); 
     } 
    } 
} 

祝你好运!

+0

这是一个非常有趣的解决方案。你将如何去提取每个对象类型的名称(在本例中为A和C)?我相信'Enum.GetName(允许)'不起作用。 –

+1

如果你运行这个例子,你会发现它实际上打印出了这个枚举的名字,如果你写入控制台允许的话,它应该会显示你加入的值。 –

编辑:

我发现莫里斯·里夫斯的回答非常好,我只是想带来一些更多的信息:

[Flags] 
    public enum ObjectType 
{ 
    None=0, 
    A = 1, 
    B = 2, 
    C = 4, 
    D = 8, 
    E = 16, 
    AorB=A|B, 
    BorCorD=B|C|D, 

} 

通过使用[Flags]属性,可以创建套枚举项目,其中可以帮助您为每组设置不同的业务规则。

为了检查和项目均存在在一组,你可以根据以下步骤做:如果你想创造的飞新项目集

public static bool IsAorB(this ObjectType item) 
{ 
     return ObjectType.AorB.HasFlag(item); 
} 

,你可以这样做:

var newGroup=ObjectType.A | ObjectType.BorCorD; 

如果要应用一些业务规则的一组,除了一个项目,你可以这样做:

var newGroupExceptC =newGroup^=ObjectType.C; 

现在,如果你检查的Elemen吨,碳集合中的存在,您会得到错误:

bool exist=newGroupExceptC.HasFlag(ObjectType.C) // =false 

更多信息,你可以找到here

+0

我已经独立地提出了相同的方法,但是'bool'返回类型不可扩展 - 如果有新的第三类事件{D,E}会怎么样。所以,我的目标是对类型进行分组。 –

+1

我的例子是检查是否是groupAorB的扩展方法,但是你可以根据需要做很多扩展。最后,你需要检查组类型,不是吗? –