简单比较枚举是否在枚举列表中

时间:2011-10-25 14:15:57

标签: c# enums

我有以下枚举:

public enum Materials { Wood, Stone, Earth, Water, Lava, Air }

现在我有3件材料可以走路(木石土)和3件不可走路(水熔岩空气)

我想比较一个标志是否是三个中的一个。

目前,我就是这样做的:

Materials myMat = Materials.Earth;
if ( myMat == Materials.Earth || myMat == Materials.Wood || myMat == Materials.Stone)
{
    I can walk on myMat...
}

是不是可以创建一个新的标志,如Materials.Walkable,它将包含这三种材料,所以我可以使用

if ( myMat == Materials.Walkable )

如果可以,我该怎么做?

提前致谢;)

5 个答案:

答案 0 :(得分:13)

您可以创建一个扩展方法:

public static bool IsWalkable(this Materials myMat )
{
    return myMat == Materials.Earth || myMat == Materials.Wood || myMat == Materials.Stone; 

    // alternatively:
    return new[] { Materials.Earth,  Materials.Wood,  Materials.Stone }.Contains(myMat);
}

并将其用作:

Materials myMat = ...
bool isMyMatWalkable = myMat.IsWalkable();

如果您愿意,还可以使用[Flags]枚举:

[Flags]
public enum Materials
{
   None = 0,
   Wood = 1,
   Stone = 1 << 1,
   Earth = 1 << 2,
   Water = 1 << 3,
   Lava = 1 << 4,
   Air = 1 << 5,
   Walkable = Wood | Earth | Stone
}

然后你可以这样做:

Materials myMat = ..
bool isMyMatWalkable = (myMat & Materials.Walkable) != Materials.None;

答案 1 :(得分:1)

System.Enum.GetValues(typeof(Materials)).Contains(myValue)

Reflection允许您获取Enum的所有值,然后检查它是否存在。 虽然,我不确定你能解决你想要做的逻辑。

如果我理解你的“逻辑”问题,你可能不得不将它变成也有一个标志的类,以表示它们是否可以步行。允许您使用linq进行查询:

var walkableAreas = AllAreas.Where(area => area.walkable);
if(walkableAreas.Contains(myArea) { //dostruff // }

这是伪代码,但我希望你得到我想解释的内容。 使用Enums你只能拥有一个值,而且你总是需要在if语句中硬编码什么是walkable和什么不是。

答案 2 :(得分:1)

您可以尝试创建自定义属性以标记材料

public enum Materials
{
    [Walkable(true)]
    Wood,
    [Walkable(true)]
    Stone,
    [Walkable(true)]
    Earth,
    [Walkable(false)]
    Water,
    [Walkable(false)]
    Lava,
    [Walkable(false)]
    Air
}

public class WalkableAttribute : Attribute
{
    public WalkableAttribute(bool value)
    {
        IsWalkable = value;
    }

    public bool IsWalkable { get; private set; }
}

然后使用扩展来检查它是否可以移动

public static class  MaterialsExtemsion
{
    public static bool IsWalkable(this Materials material)
    {
        var attribute = material.GetType().GetMember(material.ToString()).First().GetCustomAttributes(typeof(WalkableAttribute), false).FirstOrDefault();
        return attribute != null && ((WalkableAttribute) attribute).IsWalkable;
    }
}

然后使用它

        Materials material1 = Materials.Stone;
        bool result  = material1.IsWalkable();  // return true

        Materials material2 = Materials.Air;
        bool result  = material2.IsWalkable();  // return false

答案 3 :(得分:1)

也许您应该使用具有继承的类而不是仅使用Enum。这将允许您定义所有类型的属性。

public abstract class Material
{
    public abstract bool Walkable();
}


public class Wood : Material
{
    public bool Walkable()
    {
         return true;
    }
}

public class Lava: Material
{
    public bool Walkable()
    {
         return false;
    }
}

答案 4 :(得分:1)

您会考虑用实体替换枚举吗?

public class Material
{
    public string Name {get; set;}
    public bool IsWalkable {get; set;}
}

然后你可以做'直观'的操作,比如

Materials.Where(m => m.IsWalkable)