A simple comparison if the listing is on the list of listings

I have the following listing:

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

Now I have 3 materials that I could walk on (wooden stone ground) and 3 that arent walkable (water lava air)

I would like to give an opportunity to compare whether the flag is one of three.

I am currently doing this:

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

It is not possible to create a new flag, for example Materials.Walkable, which will include these three materials, so I can just use

 if ( myMat == Materials.Walkable ) 

If possible, how can I do this?

Thanks in advance;)

+6
source share
5 answers

You can 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 like:

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

If you like, you can also use the [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; 
+12
source
 System.Enum.GetValues(typeof(Materials)).Contains(myValue) 

Reflection allows you to get all the values ​​for Enum, and then check if it is present. Although, I am not sure that you can solve the logic that you are trying to do.

If I understand your “logical” problem, you will probably have to turn it into classes that also have a flag to signal if they are available. Letting you use linq to query:

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

This is pseudo code, but I hope you get what I'm trying to explain. Using Enums, you can have only one value, and you always need to rigidly indicate in the if-statement what is available and what is not.

+1
source

You can try to create a custom attribute to tag 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 the 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 
+1
source

Perhaps you should use a class with inheritance, and not just use 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; } } 
+1
source

Could you replace the Entity submenu?

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

Then you could do "intuitive" manipulations such as

 Materials.Where(m => m.IsWalkable) 
0
source

Source: https://habr.com/ru/post/900047/


All Articles