C#优化质量枚举比较

时间:2015-03-25 13:11:23

标签: c# optimization enums comparison

有没有办法优化以下代码:

enum ObjType
{
    A,
    B,
    C,
    D,
    E,
    F,
    G,
    H
}
...
if (instance.ObjType == ObjType.B
    || instance.ObjType == ObjType.D
    || instance.ObjType == ObjType.E
    || instance.ObjType == ObjType.F
    || instance.ObjType == ObjType.G
    || instance.ObjType == ObjType.H)
    doSmth();

以下解决方案不适合我:

if (instance.ObjType >= ObjType.B)
    doSmth();

因为不同的情况需要对ObjType的不同组合进行质量比较。

5 个答案:

答案 0 :(得分:2)

如果您手动分配值,请按此

enum ObjType
{
    A = 1,
    B = 2,
    C = 3,
    ...
    H = 8
}

你可以使用数字比较。

同样,如果使用枚举标志,则可以使用位掩码:

[Flags]
enum ObjType
{
    A = 1,
    B = 2,
    C = 4,
    ...
    H = 256
}

if (((ObjType.A | ObjType.B | ObjType.C) & val) != 0) {
    ...
}

答案 1 :(得分:1)

一般来说,您的代码没有任何问题。这是惯用的C#。

如果,通过“优化”,你的意思是“摆脱所有的冗余”,我建议如下:

var relevantTypes = new[] { ObjType.B, ObjType.D, ObjType.E, ... };

if (relevantTypes.Contains(instance.ObjType))
    doSmth();

局部变量只是一个示例,就个人而言,我将其设为private static readonly字段(因为您不能拥有const数组)。

如果您明智地选择名称,这也会使您的代码自我记录:

if (FooableTypes.Contains(instance.ObjType))
    doSmth();

if (TypesComparableToBar.Contains(instance.ObjType))
    doSmthElse();

答案 2 :(得分:1)

您可以将枚举定义为标记枚举

[Flags]
enum ObjType
{
    None = 0,
    A = 1 << 0,
    B = 1 << 1,
    C = 1 << 2,
    D = 1 << 3,
    E = 1 << 4,
    F = 1 << 5,
    G = 1 << 6,
    H = 1 << 7,
    MyCombination1 = A | B | D,
    MyCombination2 = C | F | G | H
}

像这样你最多可以定义32个值(加上None = 0和任意数量的其他值的组合)或最多64个值

[Flags]
enum ObjType : long
{
    None = 0,
    A = 1L << 0,
    B = 1L << 1,
    ...
}

现在你可以比较

if (instance.ObjType & ObjType.MyCombination1 != ObjType.None) {
   ...
}

如果它更适合您的需要,您还可以在枚举本身之外定义常量

private const ObjType AdHocCombination = ObjType.A | ObjType.C | ObjType.H;

定义标志时,值必须具有2的幂(None除外)。通过使用左移运算符<<可以轻松实现这一点。

答案 3 :(得分:0)

如果你必须做很多比较,并且你想让它更具可读性,那么一个可能的解决方案就是扩展方法

public static IsBDEFGH(this ObjType oType)
{
    return oType == ObjType.B
        || oType == ObjType.D
        || oType == ObjType.E
        || oType == ObjType.F
        || oType == ObjType.G
        || oType == ObjType.H;
}

然后像

一样使用它
if(instance.ObjType.IsBDEFGH())
{
}

选择一个好的名称,以便明确比较哪些值。

答案 4 :(得分:0)

根据您的需要,您可以使用[Flags],如下所示:

[Flags]
enum ObjType 
{
    SomethingSpecial = 1 << 0,
    SomethingSpecialElse = 1 << 1,

    A = (1 << 16),
    B = (1 << 17) | ObjType.SomethingSpecial,
    C = (1 << 18) | ObjType.SomethingSpecialElse,
    D = (1 << 19) | ObjType.SomethingSpecial | ObjType.SomethingSpecialElse,
}

然后,您可以使用HasFlag方法:

    ObjType.A.HasFlag(ObjType.SomethingSpecial);        // false
    ObjType.A.HasFlag(ObjType.SomethingSpecialElse);    // false
    ObjType.B.HasFlag(ObjType.SomethingSpecial);        // true
    ObjType.B.HasFlag(ObjType.SomethingSpecialElse);    // false
    ObjType.C.HasFlag(ObjType.SomethingSpecial);        // false
    ObjType.C.HasFlag(ObjType.SomethingSpecialElse);    // true
    ObjType.D.HasFlag(ObjType.SomethingSpecial);        // true
    ObjType.D.HasFlag(ObjType.SomethingSpecialElse);    // true