枚举定义中的加号运算符

Dav*_*ave 6 c# enums

我偶然发现在枚举定义中使用了加号(+)运算符,我很惊讶地看到随附的测试通过了.任何人都知道这可能记录在哪里?

public enum ApprovalItemState
{
    Enqueued = 1,
    Approved = 2,
    Denied = 4,
    Acknowledged = 8,
    ApprovalAcknowledged = ApprovalItemState.Approved + ApprovalItemState.Acknowledged,
    DenialAcknowledged = ApprovalItemState.Denied + ApprovalItemState.Acknowledged
}


[TestClass]
public class ApprovalItemStateTests
{
    [TestMethod]
    public void AreFlagsDeniedAndAcknowledged()
    {
        Assert.AreEqual(ApprovalItemState.DenialAcknowledged, ApprovalItemState.Denied | ApprovalItemState.Acknowledged);
    }

    [TestMethod]
    public void IsDenialAcknowledged()
    {
        Assert.IsTrue(Enum.IsDefined(typeof(ApprovalItemState), ApprovalItemState.Denied | ApprovalItemState.Acknowledged));
        Assert.AreEqual(ApprovalItemState.Denied | ApprovalItemState.Acknowledged, (ApprovalItemState)Enum.Parse(typeof(ApprovalItemState), "DenialAcknowledged"));
    }


    [TestMethod]
    public void IsNotDeniedAndApproved()
    {
        Assert.IsFalse(Enum.IsDefined(typeof(ApprovalItemState), ApprovalItemState.Approved | ApprovalItemState.Denied));
    }
}
Run Code Online (Sandbox Code Playgroud)

Eri*_*ert 11

里德的答案当然是正确的.我只是觉得我会添加一些有趣的琐事.首先,当你进入枚举时,枚举的所有成员都在范围内.这是C#中唯一可以通过其不合格名称使用枚举成员的情况!

public enum ApprovalItemState 
{
    Enqueued = 1,
    Approved = 2,
    Denied = 4,
    Acknowledged = 8,
    ApprovalAcknowledged = Approved | Acknowledged,
    DenialAcknowledged =  Denied | Acknowledged 
} 
Run Code Online (Sandbox Code Playgroud)

第二个琐事点是C#编译器实际上允许enum算法涉及枚举中的其他枚举!

enum E
{
    E1
}
enum F
{
    F1
}
enum G
{
    G1 = E.E1 + F.F1
}
Run Code Online (Sandbox Code Playgroud)

通常这根本不合法; 你不能在一起添加两个不同的枚举,你不能分配结果.编译器在枚举初始值设定项中放宽这些规则,以便您可以执行以下操作:

enum MyFlags
{
    MyReadOnly = FileFlags.ReadOnly,
    ...
Run Code Online (Sandbox Code Playgroud)


Ree*_*sey 10

14.5中的C#语言规范指出:

以下运算符可用于枚举类型的值:==,!=,<,>,<=,> =(§7.10.5),二进制+(§7.8.4),二进制 - (§7.8.5) ),^,&,| (§7.11.2),〜(§7.7.4),++和 - (§7.6.9和§7.7.5).

基本上,由于枚举在内部存储为Int32(默认情况下,除非您指定不同的存储类型),您可以使用这样的添加.

但是,使用|而不是+定义掩码更常见.此外,[Flags]如果您要将此作为标志枚举使用,则通常会包括在内.

  • @Dave你有效地将它视为[Flags]而不将其设置为[Flags] - 这很愚蠢.枚举中的ALWAYS状态无效,特别是因为您可以这样做:`ApprovalItemState state =(ApprovalItemState)209182309;` (2认同)