使用[Flags]和按位操作符优化C#枚举处理

在C#开发中,我们经常会遇到需要检查多个枚举值的情况。为了使代码更加简洁和可读,我们可以利用Flags特性和按位操作符来简化枚举值的比较

csharp 复制代码
public enum EnumShapeType
{
    None = 0,
    PointType,
    LineType,
    CircleType,
    BoxType,
    RectangleType,
    SphereType,
    CutFeatureType,
    CommonFeatureType,
    SweepFeatureType,
    FuseFeatureType,
    FilletFeatureType,
    HoleFeatureType,
    ExtrudeFeatureType,
    RevolveFeatureType,
    PolygonFaceFeatureType,
    PointsLineFeatureType,
    PlanarFaceFeatureType
}
if(enumShapeType == EnumShapeType.BoxType || enumShapeType == EnumShapeType.SphereType || enumShapeType == EnumShapeType.LineType || enumShapeType == EnumShapeType.PointType || enumShapeType == EnumShapeType.RectangleType)
{
    // Your code here
}

这段代码检查enumShapeType是否为EnumShapeType枚举中的五种特定类型之一:BoxType、SphereType、LineType、RectangleType和PointType

具体来说,代码使用多个逻辑或 (||) 运算符来逐一比较enumShapeType与每个目标枚举值。这种方法虽然直观,但当枚举值较多时,代码会变得冗长且难以维护

可以使用Enum类的HasFlag方法来简化这段代码

确保你的枚举类型具有[Flags]特性,每个枚举成员的值是2的幂(1, 2, 4, 8, 等),以确保它们的二进制表示形式是唯一的,这是使用[Flags]特性的关键。这样可以正确地使用按位操作符

cs 复制代码
[Flags]
public enum EnumShapeType
{
    None = 0,
    PointType= 1 << 0,
    LineType = 1 << 1,
    CircleType = 1 << 2,
    BoxType = 1 << 3,
    RectangleType = 1 << 4,
    SphereType = 1 << 5,
    CutFeatureType = 1 << 6,
    CommonFeatureType =  1 << 7,
    SweepFeatureType = 1 << 8,
    FuseFeatureType = 1 << 9,
    FilletFeatureType = 1 << 10,
    HoleFeatureType = 1 << 11,
    ExtrudeFeatureType = 1 << 12,
    RevolveFeatureType = 1 << 13,
    PolygonFaceFeatureType = 1 << 14,
    PointsLineFeatureType = 1 << 15,
    PlanarFaceFeatureType = 1 << 16
}

1 << n表示将1左移n位,相当于2的n次方

以下是每个枚举值及其对应的数值:

枚举值 数值 二级制 十六进制数值
None 0 0000 0000 0000 0000 0x0
PointType 1 0000 0000 0000 0001 0x1
LineType 2 0000 0000 0000 0010 0x2
CircleType 4 0000 0000 0000 0100 0x4
BoxType 8 0000 0000 0000 1000 0x8
RectangleType 16 0000 0000 0001 0000 0x10
SphereType 32 0000 0000 0010 0000 0x20
CutFeatureType 64 0000 0000 0100 0000 0x40
CommonFeatureType 128 0000 0000 1000 0000 0x80
SweepFeatureType 256 0000 0001 0000 0000 0x100
FuseFeatureType 512 0000 0010 0000 0000 0x200
FilletFeatureType 1024 0000 0100 0000 0000 0x400
HoleFeatureType 2048 0000 1000 0000 0000 0x800
ExtrudeFeatureType 4096 0001 0000 0000 0000 0x1000
RevolveFeatureType 8192 0010 0000 0000 0000 0x2000
PolygonFaceFeatureType 16384 0100 0000 0000 0000 0x4000
PointsLineFeatureType 32768 1000 0000 0000 0000 0x8000
PlanarFaceFeatureType 65536 1 0000 0000 0000 0000 0x10000

注意

  • C#中枚举(enum)的默认基础类型是int。这意味着在没有明确指定基础类型的情况下,枚举的每个成员将被存储为一个32位的有符号整数 (int)

  • 对于int类型,使用位标志枚举时的最大值是2147483648(1 << 31)

  • 如果需要更多的标志位,可以将枚举的基础类型更改为long,这样可以定义最多64个标志位

csharp 复制代码
[Flags]
public enum EnumShapeType : long
{
    None = 0,
    PointType = 1L << 0,
    LineType = 1L << 1,
    CircleType = 1L << 2,
    // ... 其他枚举值 ...
    PlanarFaceFeatureType = 1L << 16,
    AnotherFeatureType = 1L << 32, // 4294967296
    MaxValue = 1L << 63            // 9223372036854775808
}

使用按位操作简化检查

在简化的代码中,可以使用按位或操作符|来创建一个掩码,并使用按位与操作符&来检查多个枚举成员

复制代码
EnumShapeType shapeTypesToCheck = EnumShapeType.BoxType | EnumShapeType.SphereType | EnumShapeType.LineType | EnumShapeType.PointType | EnumShapeType.RectangleType;

if ((enumShapeType & shapeTypesToCheck) != EnumShapeType.None)
{
    // Your code here
}

使用数组和Contains方法简化

另外一种更直观和易于理解的方式(不使用[Flags]特性),可以使用一个数组来存储需要检查的枚举成员,然后利用Contains方法来简化代码

cs 复制代码
EnumShapeType[] validShapeTypes = { EnumShapeType.BoxType, EnumShapeType.SphereType, EnumShapeType.LineType, EnumShapeType.PointType, EnumShapeType.RectangleType };

if (validShapeTypes.Contains(enumShapeType))
{
    // Your code here
}
相关推荐
江畔柳前堤8 小时前
GO01-Go 语言与主流编程语言深度对比
开发语言·人工智能·后端·微服务·云原生·golang·go
世界哪有真情8 小时前
拿人类意识卡 AI?等于用 bug 验收正式产品
前端·人工智能·后端
AneiangSoft9 小时前
Aneiang.Yarp v2.3.0.25:让 AI 成为你的 API 网关运维副驾驶
网关·.net·代理·dashboard·yarp
Csvn11 小时前
Day 3:LIKE 与模式匹配 — 让查询学会"模糊搜索"
后端·sql
Hazenix12 小时前
Go 指南:一篇文章速通 Golang
开发语言·后端·golang
灯澜忆梦12 小时前
GO_复合类型---指针
开发语言·后端·golang
IT_陈寒12 小时前
SpringBoot自动装配坑了我一天,原来问题出在这
前端·人工智能·后端
星栈13 小时前
深度复盘:比 EventLoop 更隐蔽!Node 微任务堆积引发的线上接口雪崩事故
后端·node.js
名字还没想好☜13 小时前
Go slice 的 append 陷阱:共享底层数组导致的数据串改
开发语言·后端·golang·go·slice
诸神缄默不语13 小时前
FastAPI后端配置CORS中间件支持浏览器跨域访问
后端·fastapi