Reputation: 9274
I have the following enum:
public enum Materials { Wood, Stone, Earth, Water, Lava, Air }
Now I have 3materials on which i could walk (wood stone earth) and 3 which arent walkable (water lava air)
I would like to make it possible to compare if a flag is one of the three.
At the moment, this is how I do it:
Materials myMat = Materials.Earth;
if ( myMat == Materials.Earth || myMat == Materials.Wood || myMat == Materials.Stone)
{
I can walk on myMat...
}
isnt it possible to create a new flag like Materials.Walkable which would include these three materials so I can just use
if ( myMat == Materials.Walkable )
If this is possible, how can I do that?
Thanks in advance ;)
Upvotes: 7
Views: 8933
Reputation: 23276
You can try to create custom Attribute to mark your Material
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; }
}
And then use extension to check if it is Walkable
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;
}
}
then use it
Materials material1 = Materials.Stone;
bool result = material1.IsWalkable(); // return true
Materials material2 = Materials.Air;
bool result = material2.IsWalkable(); // return false
Upvotes: 1
Reputation: 107387
Would you consider replacing the enum with an Entity?
public class Material
{
public string Name {get; set;}
public bool IsWalkable {get; set;}
}
Then you could do 'intuitive' manipulation such as
Materials.Where(m => m.IsWalkable)
Upvotes: 1
Reputation: 66162
Perhaps you should use a class with inheritance instead of just using an Enum. This will allow you to define all kinds of properties.
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;
}
}
Upvotes: 1
Reputation: 113472
You could create an extension method:
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);
}
And use it as:
Materials myMat = ...
bool isMyMatWalkable = myMat.IsWalkable();
If you like, you could also use a [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
}
And then you can do:
Materials myMat = ..
bool isMyMatWalkable = (myMat & Materials.Walkable) != Materials.None;
Upvotes: 14
Reputation: 4009
System.Enum.GetValues(typeof(Materials)).Contains(myValue)
Reflection allows you to get all the values for an Enum, and then check if it's present. Although, i'm not sure you can solve the logic you're trying to do.
If I understand your "logic" problem, you'll probably have to turn it into classes that also have a flag to signal whether they're walkable. Allowing you to use linq to make the query:
var walkableAreas = AllAreas.Where(area => area.walkable);
if(walkableAreas.Contains(myArea) { //dostruff // }
It's pseudo code, but I hope you get what I'm trying to explain. Using Enums you can only have a single value, and you'll always have to hardcode in the if-statement what's walkable and what isn't.
Upvotes: 1