C#:有没有办法对枚举进行分类?

Jim*_* G. 13 c# enums classification

鉴于以下枚举:

    public enum Position
    {
        Quarterback,
        Runningback,
        DefensiveEnd,
        Linebacker
    };
Run Code Online (Sandbox Code Playgroud)

是否有可能对命名常数进行分类,这样我可以将"四分卫"和"跑卫"标记为进攻位置,将"防守端"和"后卫"标记为防守位置?

Ant*_*lev 22

您可以使用属性:

public enum Position
{
    [OffensivePosition]
    Quarterback,
    [OffensivePosition]
    Runningback,
    [DefensivePosition]
    DefensiveEnd,
    [DefensivePosition]
    Linebacker
};
Run Code Online (Sandbox Code Playgroud)

然后检查是否IsDefined合适FieldInfo.语法不是很漂亮,但你可以使用几种扩展方法来使事情更易于管理:

public static bool IsOffensivePosition(PositionType pt)
{
    return typeof(PositionType).GetField(Enum.GetName(typeof(PositionType), pt)).
        IsDefined(typeof(OffensivePositionAttribute), false);
}
Run Code Online (Sandbox Code Playgroud)


Tho*_*que 7

您可以使用属性,例如CategoryAttribute:

public enum Position
{
    [Category("Offensive")]
    Quarterback,
    [Category("Offensive")]
    Runningback,
    [Category("Defensive")]
    DefensiveEnd,
    [Category("Defensive")]
    Linebacker
};
Run Code Online (Sandbox Code Playgroud)

  • 这是一个好主意......但是一个带有辅助枚举的自定义属性可能比字符串值更好. (2认同)

Mor*_*dur 7

为什么不亲吻:

class PlayerPosition {
    public enum Position {
        Quarterback,
        Runningback,
        DefensiveEnd,
        Linebacker
    }

    public enum Type {
        Offense,
        Defense
    }


    public static Type GetTypeForPosition(Position position) {
        switch (position) {
            case Quarterback:
            case Runningback:
                return Type.Offense;
            case DefensiveEnd:
            case Linebacker:
                return Type.Defense;

        }
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 您可能想要使用除Type之外的枚举名称,其中包含System.Type和all.每次使用它时消除歧义都会非常烦人.:) (2认同)

cgr*_*eno 5

你可以使用Flags

[Flags]
public enum Position
    {
        Quarterback = 1,
        Runningback = 2,
        DefensiveEnd = 4,
        Linebacker = 8,

        OffensivePosition = Quarterback | Runningback,
        DefensivePosition =  Linebacker | DefensiveEnd, 

    };

    //strictly for example purposes
    public bool isOffensive(Position pos)
    {
        return !((pos & OffensivePosition) == pos);
    }
Run Code Online (Sandbox Code Playgroud)

  • 当使用`[Flags]`时,你还应该指定2的幂的枚举常量. (2认同)

Ser*_*kov 5

public enum PositionType
{
    Offensive,
    Defensive,
}

public class PositionTypeAttribute : Attribute
{
    public PositionTypeAttribute(PositionType positionType)
    {
        PositionType = positionType;
    }
    public PositionType PositionType { get; private set; }
}

public enum Position
{
    [PositionType(PositionType.Offensive)]
    Quarterback,
    [PositionType(PositionType.Offensive)]
    Runningback,
    [PositionType(PositionType.Defensive)]
    DefensiveEnd,
    [PositionType(PositionType.Defensive)]
    Linebacker
};

public static class PositionHelper
{
    public static PositionType GetPositionType(this Position position)
    {
        var positionTypeAttr = (PositionTypeAttribute)typeof(Position).GetField(Enum.GetName(typeof(Position), position))
            .GetCustomAttributes(typeof(PositionTypeAttribute), false)[0];
        return positionTypeAttr.PositionType;

    }
}


Position position1 = Position.Runningback;
Console.WriteLine(position1.GetPositionType()); //print: Offensive

Position position2 = Position.Linebacker;
Console.WriteLine(position2.GetPositionType()); //print: Defensive
Run Code Online (Sandbox Code Playgroud)