Простое сравнение, если перечисление находится в списке перечислений - PullRequest
7 голосов
/ 25 октября 2011

У меня есть следующее перечисление:

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 ]

13 голосов
/ 25 октября 2011

Вы можете создать метод расширения:

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] enum:

[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 голос
/ 25 октября 2011

Не могли бы вы заменить enum на Entity?

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

Тогда вы могли бы делать «интуитивные» манипуляции, такие как

Materials.Where(m => m.IsWalkable)
1 голос
/ 25 октября 2011

Возможно, вам следует использовать класс с наследованием, а не просто с помощью 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;
    }
}
1 голос
/ 25 октября 2011

Вы можете попытаться создать пользовательский атрибут, чтобы пометить ваш материал

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
1 голос
/ 25 октября 2011
System.Enum.GetValues(typeof(Materials)).Contains(myValue)

Reflection позволяет получить все значения для Enum, а затем проверить, присутствует ли он.Хотя я не уверен, что вы сможете решить логику, которую вы пытаетесь сделать.

Если я понимаю вашу «логическую» проблему, вам, вероятно, придется превратить ее в классы, которые также имеют флаг длясигнализировать, ходят ли они.Позволяет вам использовать linq для выполнения запроса:

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

Это псевдокод, но я надеюсь, вы понимаете, что я пытаюсь объяснить.Используя Enums, вы можете иметь только одно значение, и вам всегда придется жестко кодировать в операторе if что можно, а что нет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...