Check if an enum flag contains a certain flag value - c#

In C# (using Unity working on a game) I have an enum with the [Flag] attribute. I have instantiated it twice. I would like a way to compare the two enums. Specifically if enum A (which will have multiple flags) contains a flag from enum B (which will only ever be assigned a single flag).
I am not trying to compare a single instantiated enum to a single flag (this has been answered multiple times).
I suspect I could do this by dumping values with GetValue and comparing those values on a foreach loop, but it seems like there should be a more direct way to compare.
public enum AbilityType
{
None = 0,
Pierce = 1<<1,
Blunt = 1<<2,
Slash = 1<<3,
Water = 1<<4,
// etc.
};
public class Ability : MonoBehaviour
{
public AbilityType abilityType;
}
public class AbilitiedObject : StatisticalObject
{
public AbilityType resistances;
protected override void Awake()
{
base.Awake();
resistances = AbilityType.Pierce | AbilityType.Water;
}
public void TakeDamage(int damageAmount, AbilityType abilityType)
{
if( ) // Check if resistances contains abilityType's flag here
{
print("You are resistance to this damage type");
}
else
{
// Player takes damage
}
}
}
I'd like the above code to check if resistances contains the flag from abilityType. In the example above, the attack in question will pass it's abilityType in. If that type is water or pierce, it should print the resistance statement. If it's another type, it should deal damage as normal.

What you want is to abuse, as stated in the comments and other answers, is the bitwise & operator to compare as enums are (by default) based on the int type. However since .NET 4.0 there has been the addition of Enum.HasFlag extension method that does exactly this and increases readability.
// These two are semantically equal
if (resistance.HasFlag(abilityType))
{
print("You are resistance to this damage type");
}
if ((resistance & abilityType) != 0)
{
print("You are resistance to this damage type");
}
Behind the scenes of this is explained by numerous others. Can personally recommend Alan Zucconi's Enum, Flags and bitwise operators
Short version is that the bitwise AND (&) operator gives a result of where two values "match" in the sense that they're both active, bit by bit. One way to think of it is as a selective filter. To check if a value A of unknown flag set contains a specific flag B, you use the filter which only allows flag B to pass through and check if anything got through, where anything is represented as anything else than zero. The filter is simply the same as the flag you wish to look for. Therefore the expression becomes (A & B) != 0. Parentheses to force override order of operations since != has higher precedence than &.

Here's what you need:
if ((resistances & abilityType) != 0)
{
print("You are resistance to this damage type");
}
...

Related

How to define a catch-all enum value when casting from an integer?

I've got a enum type defined in my C# code that corresponds to all possible values for the NetConnectionStatus field in Win32_NetworkAdapter WMI table, as documented here.
The documentation shows that the integers 0 through 12 each have a unique status name, but then all integers between 13 and 65,535 are lumped into one bucket called "Other." So here's my code:
[Serializable]
public enum NetConnectionStatus
{
Disconnected = 0,
Connecting = 1,
Connected = 2,
Disconnecting = 3,
HardwareNotPresent = 4,
HardwareDisabled = 5,
HardwareMalfunction = 6,
MediaDisconnected = 7,
Authenticating = 8,
AuthenticationSucceeded = 9,
AuthenticationFailed = 10,
InvalidAddress = 11,
CredentialsRequired = 12,
Other
}
This works fine for the values that are not Other. For instance, I can do this:
var result = (NetConnectionStatus) 2;
Assert.AreEqual(NetConnectionStatus.Connected, result);
But for anything in that higher numeric range, it doesn't work so great. I would like it if I could do this:
var result = (NetConnectionStatus) 20;
Assert.AreEqual(NetConnectionStatus.Other, result);
But right now that result variable gets assigned the literal value 20 instead of Other. Is there some out-of-the-box way of accomplishing this, something akin to Parse() but for integers instead of strings, or perhaps some special attribute I'm unaware of? I would prefer to not write my own wrapper method for this if there is already a good way to accomplish this.
If you have a string value, then the closest thing I can think of is to use Enum.TryParse:
NetConnectionStatus result;
if (Enum.TryParse(stringValue, out result) == false)
result = NetConnectionStatus.Other;
For an integer value that you're casting, you can use:
result = (NetConnectionStatus)integerValue;
if (Enum.GetValues(typeof(NetConnectionStatus)).Contains(result) == false)
result = NetConnectionStatus.Other;
Not really ideal, but in C# enums aren't much more than fancy names for integral values, so it's valid to stuff an integer value not in the defined values of the enums into a value of that enum type.
This solution will handle negative numbers, or cases where you have gaps in your enum values more elegantly than doing numerical comparisons.
it would be nice but no. How about
var result = (NetConnectionStatus) 20;
Assert.IsTrue(result >= (int)NetConnectionStatus.Other);
.NET does not such thing as a "any other" enumeration value bucket. Technically, enumeration (enum) is a pretty set of named constants of some underlying type (which is one of following: sbyte, short, int, long and their unsigned counterparts). You can cast an enum value to/from a corresponding type without any losses, as in this example:
enum TestEnum:int // Explicitly stating a type.
{
OnlyElement=0
}
class Program
{
static void Main(string[] args)
{
// Console.WriteLine implicitly calls ToString of the TestEnum.OnlyElement.
Console.WriteLine("OnlyElement == {0}", TestEnum.OnlyElement);
//TestEnum.OnlyElement equals to 0, as demonstrated by this casting:
Console.WriteLine("(int)OnlyElement == {0}", (int)TestEnum.OnlyElement);
//We can do it in reverse...
Console.WriteLine("(TestEnum)0 == ",(TestEnum)0);
// But what happens when we try to cast a value, which is not
// representable by any of enum's named constants,
// into value of enum in question? No exception is thrown
// whatsoever: enum variable simply holds that value, and,
// having no named constant to associate it with, simply returns
// that value when attempting to "ToString"ify it:
Console.WriteLine("(TestEnum)5 == {0}", (TestEnum)5); //prints "(TestEnum)5 == 5".
Console.ReadKey();
}
}
I'd like to repeat it again, enum in .NET is simply a value of the underlying type with some nice decorations like overriden ToString method and flags checking (look here or here if you want to know more about flags). You cannot have an integer with only 14 values like "0..12 and everything else", and so you cannot have such enum. In your example, NetConnectionStatus.Other simply receives single literal value (I assume it would most probably be '13', as the next available positive value of underlying type - however it actually depends on the compiler) as any other enumeration constant would do if not specified explicitly - and, obviously, it does not become a bucket.
However, there are options to achieve simple equation checks for integers/bytes/shorts/longs - and enums alike. Consider this extension method:
static bool IsOther(this NetConnectionStatus A)
{
return (A < (NetConnectionStatus)0) || (A > (NetConnectionStatus)12);
}
Now you can have a simple assertion like this:
var result = (NetConnectionStatus)10;
Trace.Assert(result.IsOther()); //No assertion is triggered; result is NetConnectionStatus.AuthenticationFailed
and
var result = (NetConnectionStatus)20;
Trace.Assert(result.IsOther()); //Assertion failed; result is undefined!
(Of course you can replace IsOther method with IsNotOther, overload it and pretty much anything else you could do with a method.)
Now there is one more thing. Enum class itself contains a method called IsDefined, which allows you to avoid checks for specific enum's value boundaries (<0, >12), therefore preventing unwanted bugs in case enum values would ever be added/removed, at the small performance cost of unboxing and checking each value in enum for a match (I'm not sure how this works under the hood though, I hope these checks are optimized). So your method would look like this:
static bool IsOther(NetConnectionStatus A)
{
return !Enum.IsDefined(typeof(NetConnectionStatus), A);
}
(However, concluding from enum's name, it seems like you want to make a network application/server, and for these performance might be of very great importance - but most probably I'm just being paranoid and this will not be your application's bottleneck. Stability is much more of concern, and, unless you experience real troubles with performance, it is considered to be much better practice to enable as much stability&safety&portability as possible. Enum.IsDefined is much more understandable, portable and stable than the explicit boundaries checking.)
Hope that helps!
Thanks everyone for the replies. As confirmed by all of you, there is indeed no way to do this out-of-the-box. For the benefit of others I thought I'd post the (custom) code I ended up writing. I wrote an extension method that utilizes a custom attribute on the enum value that I called [CatchAll].
public class CatchAll : Attribute { }
public static class EnumExtensions
{
public static T ToEnum<T, U>(this U value) where T : struct, IConvertible where U : struct, IComparable, IConvertible, IFormattable, IComparable<U>, IEquatable<U>
{
var result = (T)Enum.ToObject(typeof(T), value);
var values = Enum.GetValues(typeof(T)).Cast<T>().ToList();
if (!values.Contains(result))
{
foreach (var enumVal in from enumVal in values
let info = typeof(T).GetField(enumVal.ToString())
let attrs = info.GetCustomAttributes(typeof(CatchAll), false)
where attrs.Length == 1
select enumVal)
{
result = enumVal;
break;
}
}
return result;
}
}
So then I just have to apply that [CatchAll] attribute to the Other value in the enum definition. Then I can do things like this:
int value = 13;
var result = value.ToEnum<NetConnectionStatus, int>();
Assert.AreEqual(NetConnectionStatus.Other, result);
And this:
ushort value = 20;
result = value.ToEnum<NetConnectionStatus, ushort>();
Assert.AreEqual(NetConnectionStatus.Other, result);

c# which is the better way to declare two parameters

I have a very quick question about the best way to use two variables. Essentially I have an enum and an int, the value for which I want to get within several ifs. Should I declare them outside the if's or inside - consider the following examples:
e.g.a:
public void test() {
EnumName? value = null;
int distance = 0;
if(anotherValue == something) {
distance = 10;
value = getValue(distance);
}
else if(anotherValue == somethingElse) {
distance = 20;
value = getValue(distance);
}
if (value == theValueWeWant){
//Do something
}
OR
e.g.2
public void test() {
if(anotherValue == something) {
int distance = 10;
EnumType value = getValue(distance);
if (value == theValueWeWant){
//Do something
}
else if(anotherValue == somethingElse) {
int distance = 20;
EnumType value = getValue(distance);
if (value == theValueWeWant){
//Do something
}
}
I am just curious which is best? or if there is a better way?
Purely in terms of maintenance, the first code block is better as it does not duplicate code (assuming that "Do something" is the same in both cases).
In terms of performance, the difference should be negligible. The second case does generate twice as many locals in the compiled IL, but the JIT should notice that their usage does not overlap and optimize them away. The second case is also going to cause emission of the same code twice (if (value == theValueWeWant) { ...), but this should also not cause any significant performance penalty.
(Though both aspects of the second example will cause the compiled assembly to be very slightly larger, more IL does not always imply worse performance.)
Both examples do two different things:
Version 1 will run the same code if you get the desired value, where as Version 2 will potentially run different code even if you get the desired value.
There's a lot of possible (micro)optimizations you could do.
For Example, if distance is only ever used in getValue(distance), you could get rid of it entirely:
/*Waring, micro-optimization!*/
public void test() {
EnumType value = getValue((anotherValue == something) ? 10 : (anotherValue == somethingElse) ? 20 : 0);
if (value == theValueWeWant){
//Do something
}
}
If you wish to use those later on, then g for the second method. Those variables will be lost as soon as they're out of scope.
Even if you don't want to use them later, declaring them before the if's is something you should do, to avoid code repetition.
This question is purely a matter of style and hence has no correct answer, only opinions
The C# best practice is generally to declare variables in the scope where they are used. This would point to the second example as the answer. Even though the types and names are the same, they represent different uses and should be constrained to the blocks in which they are created.

C# - using a generic enum (or alternative method for controlling lists)

I'm writing a pathfinding algorithm for a game, but trying to keep it generic so it can be used in future applications.
I have a Node class which holds X, Y and "PassableType".
The NodeGrid class stores an array of Nodes, containing the graph information of how they connect, and then has a FindAStarPath() function, which takes as its parameters StartNode, EndNode, and params for "PassableTypes".
My problem is determining what type "PassableType" should have.
Ideally what I want is to be able to use a generic enum - i.e. a restricted list which each game defines. The Node will hold a single element of that list, to say what path type it is (the current game may use Path, Grass, Wall, etc)
Thus, when an entity tries to path, it provides the pathfinding function which types to treat as "passable". So a man may use
FindAStarPath(CurrentNode, DestinationNode, "Path", "Floor", "Door");
but a car may just use
FindAStarPath(StartNode, EndNode, "Road");
My problem is I can't work out how to get the NodeGrid to take a Generic enum or equivalent logic.
At the moment I have it taking strings, but this means I have to write
MyEnum.Road.ToString()
every time I use it.
Ideally I'd like to do something like
NodeGrid<MyEnum> CurrentNodeGrid = new NodeGrid<MyEnum>()
And then Nodes will take a MyEnum for their passableType, as will the pathfinding functions, thus allowing each game to have a different set of tile types for pathing.
But I can't define NodeGrid as:
public class NodeGrid<T> where T:enum
For clarity, the only part of the pathfinding function which uses this enum is this (contained within Node):
public bool IsPassable(string[] passableTypes)
{
for (var i = 0; i < passableTypes.Count(); i++)
{
if (this.PassableType == passableTypes[i]) return true;
}
return false;
}
Thanks
Haighstrom
Unless you're using some specific functionality of enums (like Enum.Parse), then I don't see any reason to constrain it to them. By freeing constraints, callers can use whatever types they see fit, beit enum, or a set of string values (as you currently have it), or a set of custom class instances to check against.
public class NodeGrid<T>
{
public T PassableType { get; private set; }
public bool IsPassable(params T[] passableTypes)
{
return IsPassable((IEnumerable<T>)passableTypes);
}
public bool IsPassable(IEnumerable<T> passableTypes)
{
foreach(T passType in passableTypes)
{
if (EqualityComparer<T>.Default.Equals(this.PassableType, passType))
return true;
}
return false;
}
}
But since we're now using generics, you can't use the == comparison anymore. The simplest is to leverage the EqualityComparer.Default utility. The main reason to use this over directly calling this.PassableType.Equals(passType) is it will perform null checks and leverage generics properly where applicable and if the types implement IEquatable<T>, then use those generic versions. Probably some other minor things. It will usually eventually call the Object.Equals overload.
Some examples based on your question:
//using a custom enum, calls the params T[] overload
NodeGrid<MyCarEnum> carNode = ...
carNode.IsPassable(MyCarEnum.Road, MyCarEnum.Tunnel);
//demonstrates receiving a set of pass types strings from an external source
List<string> passTypes = new List<string>("Path", "Floor", "Door");
NodeGrid<string> personNode = ...
personNode.IsPassable(passTypes) //calls the IEnumerable<T> overload
//feel free to declare enums wherever you want,
//it can avoid potential mixups like this:
NodeGrid<string> airplaneNode = ...
NodeGrid<string> personNode = ...
NodeGrid<MyCarEnum> carNode = ...
airplaneNode.IsPassable("Floor"); //makes no sense, but will compile
personNode.IsPassable("Clouds"); //makes no sense, but will compile
carNode.IsPassable("Sky"); //compile error: was expected a MyCarEnum value

Objects with many value checks c#

I want to see your ideas on a efficient way to check values of a newly serialized object.
Example I have an xml document I have serialized into an object, now I want to do value checks. First and most basic idea I can think of is to use nested if statments and checks each property, could be from one value checking that it has he correct url format, to checking another proprieties value that is a date but making sue it is in the correct range etc.
So my question is how would people do checks on all values in an object? Type checks are not important as this is already taken care of it is more to do with the value itself. It needs to be for quite large objects this is why I did not really want to use nested if statements.
Edit:
I want to achieve complete value validation on all properties in a given object.
I want to check the value it self not that it is null. I want to check the value for specific things if i have, an object with many properties one is of type string and named homepage.
I want to be able to check that the string in the in the correct URL format if not fail. This is just one example in the same object I could check that a date is in a given range if any are not I will return false or some form of fail.
I am using c# .net 4.
Try to use Fluent Validation, it is separation of concerns and configure validation out of your object
public class Validator<T>
{
List<Func<T,bool>> _verifiers = new List<Func<T, bool>>();
public void AddPropertyValidator(Func<T, bool> propValidator)
{
_verifiers.Add(propValidator);
}
public bool IsValid(T objectToValidate)
{
try {
return _verifiers.All(pv => pv(objectToValidate));
} catch(Exception) {
return false;
}
}
}
class ExampleObject {
public string Name {get; set;}
public int BirthYear { get;set;}
}
public static void Main(string[] args)
{
var validator = new Validator<ExampleObject>();
validator.AddPropertyValidator(o => !string.IsNullOrEmpty(o.Name));
validator.AddPropertyValidator(o => o.BirthYear > 1900 && o.BirthYear < DateTime.Now.Year );
validator.AddPropertyValidator(o => o.Name.Length > 3);
validator.Validate(new ExampleObject());
}
I suggest using Automapper with a ValueResolver. You can deserialize the XML into an object in a very elegant way using autommaper and check if the values you get are valid with a ValueResolver.
You can use a base ValueResolver that check for Nulls or invalid casts, and some CustomResolver's that check if the Values you get are correct.
It might not be exacly what you are looking for, but I think it's an elegant way to do it.
Check this out here: http://dannydouglass.com/2010/11/06/simplify-using-xml-data-with-automapper-and-linqtoxml
In functional languages, such as Haskell, your problem could be solved with the Maybe-monad:
The Maybe monad embodies the strategy of combining a chain of
computations that may each return Nothing by ending the chain early if
any step produces Nothing as output. It is useful when a computation
entails a sequence of steps that depend on one another, and in which
some steps may fail to return a value.
Replace Nothing with null, and the same thing applies for C#.
There are several ways to try and solve the problem, none of them are particularly pretty. If you want a runtime-validation that something is not null, you could use an AOP framework to inject null-checking code into your type. Otherwise you would really have to end up doing nested if checks for null, which is not only ugly, it will probably violate the Law of Demeter.
As a compromise, you could use a Maybe-monad like set of extension methods, which would allow you to query the object, and choose what to do in case one of the properties is null.
Have a look at this article by Dmitri Nesteruk: http://www.codeproject.com/Articles/109026/Chained-null-checks-and-the-Maybe-monad
Hope that helps.
I assume your question is: How do I efficiently check whether my object is valid?
If so, it does not matter that your object was just deserialized from some text source. If your question regards checking the object while deserializing to quickly stop deserializing if an error is found, that is another issue and you should update your question.
Validating an object efficiently is not often discussed when it comes to C# and administrative tools. The reason is that it is very quick no matter how you do it. It is more common to discuss how to do the checks in a manner that is easy to read and easily maintained.
Since your question is about efficiency, here are some ideas:
If you have a huge number of objects to be checked and performance is of key importance, you might want to change your objects into arrays of data so that they can be checked in a consistent manner. Example:
Instead of having MyObject[] MyObjects where MyObject has a lot of properties, break out each property and put them into an array like this:
int[] MyFirstProperties
float[] MySecondProperties
This way, the loop that traverses the list and checks the values, can be as quick as possible and you will not have many cache misses in the CPU cache, since you loop forward in the memory. Just be sure to use regular arrays or lists that are not implemented as linked lists, since that is likely to generate a lot of cache misses.
If you do not want to break up your objects into arrays of properties, it seems that top speed is not of interest but almost top speed. Then, your best bet is to keep your objects in a serial array and do:
.
bool wasOk = true;
foreach (MyObject obj in MyObjects)
{
if (obj.MyFirstProperty == someBadValue)
{
wasOk = false;
break;
}
if (obj.MySecondProperty == someOtherBadValue)
{
wasOk = false;
break;
}
}
This checks whether all your objects' properties are ok. I am not sure what your case really is but I think you get the point. Speed is already great when it comes to just checking properties of an object.
If you do string compares, make sure that you use x = y where possible, instead of using more sophisticated string compares, since x = y has a few quick opt outs, like if any of them is null, return, if the memory address is the same, the strings are equal and a few more clever things if I remember correctly. For any Java guy reading this, do not do this in Java!!! It will work sometimes but not always.
If I did not answer your question, you need to improve your question.
I'm not certain I understand the depth of your question but, wouldn't you just do somthing like this,
public SomeClass
{
private const string UrlValidatorRegex = "http://...
private const DateTime MinValidSomeDate = ...
private const DateTime MaxValidSomeDate = ...
public string SomeUrl { get; set; }
public DateTime SomeDate { get; set; }
...
private ValidationResult ValidateProperties()
{
var urlValidator = new RegEx(urlValidatorRegex);
if (!urlValidator.IsMatch(this.Someurl))
{
return new ValidationResult
{
IsValid = false,
Message = "SomeUrl format invalid."
};
}
if (this.SomeDate < MinValidSomeDate
|| this.SomeDate > MinValidSomeDate)
{
return new ValidationResult
{
IsValid = false,
Message = "SomeDate outside permitted bounds."
};
}
...
// Check other fields and properties here, return false on failure.
...
return new ValidationResult
{
IsValid = true,
};
}
...
private struct ValidationResult
{
public bool IsValid;
public string Message;
}
}
The exact valdiation code would vary depending on how you would like your class to work, no? Consider a property of a familar type,
public string SomeString { get; set; }
What are the valid values for this property. Both null and string.Empty may or may not be valid depending on the Class adorned with the property. There may be maximal length that should be allowed but, these details would vary by implementation.
If any suggested answer is more complicated than code above without offering an increase in performance or functionality, can it be more efficient?
Is your question actually, how can I check the values on an object without having to write much code?

Extending an enum via inheritance

I know this rather goes against the idea of enums, but is it possible to extend enums in C#/Java? I mean "extend" in both the sense of adding new values to an enum, but also in the OO sense of inheriting from an existing enum.
I assume it's not possible in Java, as it only got them fairly recently (Java 5?). C# seems more forgiving of people that want to do crazy things, though, so I thought it might be possible some way. Presumably it could be hacked up via reflection (not that you'd every actually use that method)?
I'm not necessarily interested in implementing any given method, it just provoked my curiosity when it occurred to me :-)
The reason you can't extend Enums is because it would lead to problems with polymorphism.
Say you have an enum MyEnum with values A, B, and C , and extend it with value D as MyExtEnum.
Suppose a method expects a myEnum value somewhere, for instance as a parameter. It should be legal to supply a MyExtEnum value, because it's a subtype, but now what are you going to do when it turns out the value is D?
To eliminate this problem, extending enums is illegal
You're going the wrong way: a subclass of an enum would have fewer entries.
In pseudocode, think:
enum Animal { Mosquito, Dog, Cat };
enum Mammal : Animal { Dog, Cat }; // (not valid C#)
Any method that can accept an Animal should be able to accept a Mammal, but not the other way around. Subclassing is for making something more specific, not more general. That's why "object" is the root of the class hierarchy. Likewise, if enums were inheritable, then a hypothetical root of the enum hierarchy would have every possible symbol.
But no, C#/Java don't allow sub-enums, AFAICT, though it would be really useful at times. It's probably because they chose to implement Enums as ints (like C) instead of interned symbols (like Lisp). (Above, what does (Animal)1 represent, and what does (Mammal)1 represent, and are they the same value?)
You could write your own enum-like class (with a different name) that provided this, though. With C# attributes it might even look kind of nice.
When built-in enums aren't enough, you can do it the old fashion way and craft your own. For example, if you wanted to add an additional property, for example, a description field, you could do it as follows:
public class Action {
public string Name {get; private set;}
public string Description {get; private set;}
private Action(string name, string description) {
Name = name;
Description = description;
}
public static Action DoIt = new Action("Do it", "This does things");
public static Action StopIt = new Action("Stop It", "This stops things");
}
You can then treat it like an enum like so:
public void ProcessAction(Action a) {
Console.WriteLine("Performing action: " + a.Name)
if (a == Action.DoIt) {
// ... and so on
}
}
The trick is to make sure that the constructor is private (or protected if you want to inherit), and that your instances are static.
Enums are supposed to represent the enumeration of all possible values, so extending rather does go against the idea.
However, what you can do in Java (and presumably C++0x) is have an interface instead of a enum class. Then put you standard values in an enum that implements the feature. Obviously you don't get to use java.util.EnumSet and the like. This is the approach taken in "more NIO features", which should be in JDK7.
public interface Result {
String name();
String toString();
}
public enum StandardResults implements Result {
TRUE, FALSE
}
public enum WTFResults implements Result {
FILE_NOT_FOUND
}
You can use .NET reflection to retrieve the labels and values from an existing enum at run-time (Enum.GetNames() and Enum.GetValues() are the two specific methods you would use) and then use code injection to create a new one with those elements plus some new ones. This seems somewhat analagous to "inheriting from an existing enum".
I didn't see anyone else mention this but the ordinal value of an enum is important. For example, with grails when you save an enum to the database it uses the ordinal value. If you could somehow extend an enum, what would be the ordinal values of your extensions? If you extended it in multiple places how could you preserve some kind of order to these ordinals? Chaos/instability in the ordinal values would be a bad thing which is probably another reason why the language designers have not touched this.
Another difficulty if you were the language designer, how can you preserve the functionality of the values() method which is supposed to return all of the enum values. What would you invoke this on and how would it gather up all of the values?
Adding enums is a fairly common thing to do if you go back to the source code and edit, any other way (inheritance or reflection, if either is possible) is likely to come back and hit you when you get an upgrade of the library and they have introduced the same enum name or the same enum value - I have seen plenty of lowlevel code where the integer number matches to the binary encoding, where you would run into problems
Ideally code referencing enums should be written as equals only (or switches), and try to be future proof by not expecting the enum set to be const
If you mean extends in the Base class sense, then in Java... no.
But you can extend an enum value to have properties and methods if that's what you mean.
For example, the following uses a Bracket enum:
class Person {
enum Bracket {
Low(0, 12000),
Middle(12000, 60000),
Upper(60000, 100000);
private final int low;
private final int high;
Brackets(int low, int high) {
this.low = low;
this.high = high;
}
public int getLow() {
return low;
}
public int getHigh() {
return high;
}
public boolean isWithin(int value) {
return value >= low && value <= high;
}
public String toString() {
return "Bracket " + low + " to " + high;
}
}
private Bracket bracket;
private String name;
public Person(String name, Bracket bracket) {
this.bracket = bracket;
this.name = name;
}
public String toString() {
return name + " in " + bracket;
}
}
Saw a post regarding this for Java a while back, check out http://www.javaspecialists.eu/archive/Issue161.html .
I would like to be able to add values to C# enumerations which are combinations of existing values. For example (this is what I want to do):
AnchorStyles is defined as
public enum AnchorStyles {
None = 0,
Top = 1,
Bottom = 2,
Left = 4,
Right = 8,
}
and I would like to add an AnchorStyles.BottomRight = Right + Bottom so instead of saying
my_ctrl.Anchor = AnchorStyles.Right | AnchorStyles.Bottom;
I can just say
my_ctrl.Anchor = AnchorStyles.BottomRight;
This doesn't cause any of the problems that have been mentioned above, so it would be nice if it was possible.
A temporary/local workaround, when you just want very local/one time usage:
enum Animals { Dog, Cat }
enum AnimalsExt { Dog = Animals.Dog, Cat= Animals.Cat, MyOther}
// BUT CAST THEM when using:
var xyz = AnimalsExt.Cat;
MethodThatNeedsAnimal( (Animals)xyz );
See all answers at: Enum "Inheritance"
You can't inherit from/extend an enum, you can use attributes to declare a description. If you're looking for an integer value, that's built-in.
Hmmm - as far as I know, this can't be done - enumerations are written at design-time and are used as a convenience to the programmer.
I'm pretty sure that when the code is compiled, the equivalent values will be substituted for the names in your enumeration, thereby removing the concept of an enumeration and (therefore) the ability to extend it.
Some time back even i wanted to do something like this and found that enum extensions would voilate lot of basic concepts... (Not just polymorphisim)
But still u might need to do if the enum is declared in external library and
Remember you should make a special caution when using this enum extensions...
public enum MyEnum { A = 1, B = 2, C = 4 }
public const MyEnum D = (MyEnum)(8);
public const MyEnum E = (MyEnum)(16);
func1{
MyEnum EnumValue = D;
switch (EnumValue){
case D: break;
case E: break;
case MyEnum.A: break;
case MyEnum.B: break;
}
}
As far as java is concerned it is not allowed because adding elements to an enum would effectively create a super class rather than a sub class.
Consider:
enum Person (JOHN SAM}
enum Student extends Person {HARVEY ROSS}
A general use case of Polymorphism would be
Person person = Student.ROSS; //not legal
which is clearly wrong.

Categories