C# C语言中enum成员的并集#

C# C语言中enum成员的并集#,c#,enums,grouping,C#,Enums,Grouping,比如说,我有一个enum BasicType,它的定义如下: public enum ObjectType{ A = 1, B = 2, C = 3, } 基本类型标识对任何对象执行三元分类。随后,我意识到需要以与C类似的方式处理对象A和B,因此我定义了另一个enum ObjectGroupType,如下所示: public enum ObjectGroupType { AB = 1, C = 2, } 使用新的en

比如说,我有一个
enum BasicType
,它的定义如下:

    public enum ObjectType{
        A = 1,
        B = 2,
        C = 3,
    }
基本类型标识对任何
对象执行三元分类。随后,我意识到需要以与C类似的方式处理对象A和B,因此我定义了另一个
enum ObjectGroupType
,如下所示:

public enum ObjectGroupType
{
   AB = 1,
   C = 2,
}
使用新的enum,我能够将几种已知类型的对象作为一个对象进行bucket。所以,当我接收到各种类型的对象流时,我实际上确定它们是属于AB型还是C型。有没有一个优雅的解决办法?例如,我能否在
ObjectGroupType
中为A和B分配相同的枚举值

编辑1:我找不到与问题相似之处

编辑2:感谢莫里斯的建设性意见——根据您的回答,我提出了这个重新定义的
ObjectGroupType

 public enum ObjectGroupType
 {
    AB = ObjectType.A | ObjectType.B
    C = 2,
 }
这有效吗

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

    object
    /     \
 AB        C
 /\
A  B

您可以使用int而不是enum,使用组合时不重叠的值(即二进制表示只有一位的值),然后对参数的ObjectType执行掩码操作以确定其是否为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); });
    }
}
class-SomeClass
{
公共静态类ObjectType
{
公共常数INTA=1;
公共常数int B=2;
公共常数int C=4;
公共常数int D=8;
}
公共int-MyType;
公共字符串标题;
静态void Main(字符串[]参数)
{
列表=新列表()
{
新建SomeClass(){Title=“我属于类型A”,MyType=ObjectType.A}
,new SomeClass(){Title=“我属于类型B”,MyType=ObjectType.B}
,new SomeClass(){Title=“我属于AB型”,MyType=ObjectType.A | ObjectType.B}
};
list.ForEach(p=>{if(p.MyType==(ObjectType.A | ObjectType.B))Console.WriteLine(p.Title);});
}
}

这种方法的缺点是丢失了对象类型的强类型,即您可以分配任何值,而不仅仅是您在ObjectType中定义的值。

您可以使用int而不是enum,使用组合时不重叠的值(即二进制表示只有一位的值)然后对参数的ObjectType执行掩码操作,以确定其是否为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); });
    }
}
class-SomeClass
{
公共静态类ObjectType
{
公共常数INTA=1;
公共常数int B=2;
公共常数int C=4;
公共常数int D=8;
}
公共int-MyType;
公共字符串标题;
静态void Main(字符串[]参数)
{
列表=新列表()
{
新建SomeClass(){Title=“我属于类型A”,MyType=ObjectType.A}
,new SomeClass(){Title=“我属于类型B”,MyType=ObjectType.B}
,new SomeClass(){Title=“我属于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);
        }
    }
}

祝你好运

如果我误读了您的意图,我提前表示歉意,但听起来您似乎希望在代码中基于枚举值对多个不同的枚举类型进行操作。好的方面是,您已经可以通过按位操作和枚举实现这一点

给定如下所示的枚举:

[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);
        }
    }
}
祝你好运

编辑:

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

   [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;
如果要对集合(项目除外)应用某些业务规则,可以执行以下操作:

var newGroup=ObjectType.A | ObjectType.BorCorD;
var newGroupExceptC =newGroup^=ObjectType.C;
现在,如果检查集合中是否存在元素C,则会得到false:

bool exist=newGroupExceptC.HasFlag(ObjectType.C) // =false
有关更多信息,请参见编辑:

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

   [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;
如果你想申请