This question already has answers here:
Non-unique enum values
(8 answers)
Closed 9 years ago.
In .NET can you have multiple enum values for the same integer?
eg.
public enum PersonGender
{
Unknown = 0,
Male = 1,
Female = 2,
Intersex = 3,
Indeterminate = 3,
NonStated = 9,
InadequatelyDescribed = 9
}
In C#, this is allowed, as per the C# Language Specication, version 4. Section 1.10 Enums doesn't explicitly mention the possibility but, later on in section 14 Enums, 14.3, we see:
Multiple enum members may share the same associated value. The example
enum Color {
Red,
Green,
Blue,
Max = Blue
}
shows an enum in which two enum members - Blue and Max - have the same associated value.
That works fine. There is absolutely nothing wrong with the code you posted. It compiles just fine and works in code, with the caveat that
PersonGender.NonStated == PersonGender.InadequatelyDescribed
I found this StackOverflow post related to this question. I think there is a very sensible discussion of how this works. Non-unique enum values
Now, I might also add that it is my opinion this would be an ambiguous (and therefore improper) use of an enum. It's important to write code that makes sense to someone else reading it, and in this case, I would be put off by this enum.
I would suggest that an enum would not be a right thing to use in your context instead you can use create a class and methods which can resolve your purpose. Something like this in your class:-
class A
{
static readonly ABCD= new Dictionary<int,string>
{
{ 1, "X" },
{ 2, "X" },
{ 3, "Y" }
{ 4, "Y" }
}
}
Related
This question already has answers here:
Extension method on enumeration, not instance of enumeration
(7 answers)
Closed 8 years ago.
I wonder why we can't add static methods (only methods, not properties) into enums? Is there any explanation for that?
It would be very useful if it was allowed.
And I also want to learn who forbids us to do it? Is it IL or C#?
Edit:
I don't want to use extension methods. Because I dont need to pass an instance of that enum. I don't need it's value there...
I want to call something like FooTypes.GetGoodFoos() not something FooTypes.BadFoo.GetSomething()
Edit 2:
Is that only me who thinks this could be more useful rather than writing this method in another class?
public enum Colors
{
Red,
LightRed,
Pink,
/* .
.
. */
Green
public static Colors[] GetRedLikes()
{
return new Colors[]
{
Colors.Red,
Colors.LightRed,
Colors.Pink
}
}
}
As the other answers say, it's not possible.
I know, this does not answer your question, but I want to give an alternative to your example.
Because, basically what you try to archive is already possible with flags. So let me take your "GetRedLikes" example:
[Flags]
public enum Colors : byte
{
Transparent = 0, // = 0 (00000000)
Red = 1 << 0, // = 1 (00000001)
LightRed = 1 << 1, // = 2 (00000010)
Pink = 1 << 2, // = 4 (00000100)
Green = 1 << 3, // = 8 (00001000)
RedLikes = Colors.Red | Colors.LightRed | Colors.Pink // = 7 (00000111)
}
Then Colors.RedLikes will contain Red, LightRed and Pink. All the magic is done by bits, as always. Your condition then should look like this:
Colors c = Colors.LightRed;
if(c & Colors.RedLikes != 0)
{
// c is red-alike
}
Of course, this solution will not allow you to do very complex algorithms, it's no method type replacement. But it allows you to combine more than one enum in a set. If you need further functions, you have to build a method in an extra class.
I use static class for same cases:
public enum SomeEnum
{
Item1,
Item2,
Item3
}
public static class SomeEnumHelper
{
public static SomeEnum[] GetMainItems()
{
return new[] {SomeEnum.Item1, SomeEnum.Item2};
}
}
We can't add methods to enums because is how the language is made, and you are free to read the specification of the C# Language Specification
14.3 Enum members
The body of an enum type declaration defines zero or more enum members, which are the named constants of the enum type. No
two enum members can have the same name.
enum-member-declarations: enum-member-declaration
enum-member-declarations , enum-member-declaration
enum-member-declaration: attributesopt identifier attributesopt
identifier = constant-expression
Each enum member has an
associated constant value. The type of this value is the underlying
type for the containing enum. The constant value for each enum member
must be in the range of the underlying type for the enum.
I have an enum:
[DataContract]
public enum Relationship
{
Spouse = 4,
ResidesWith = 1,
Parent = 2,
Other = 3,
PersonalGuarantor = 5,
CoApplicant = 6
}
As you can see, zero is not defined. I built my program around the idea that zero would never be defined in enums. That allows me to see which ones have been set from various comboBoxes, and which ones were set to a null value. If I set zero as the null value, there is no way to tell those two things apart, and it essential that I be able to.
Due to the lack of a default state, I get an error when I try to serialize the values.
Is there a way to have my xml serialize skip enums that have no value, or a way to avoid those errors? I really do not want to introduce a default value.
You need to use 0 as an enum value - make it a value that is not valid and that you check for (as you are already).
[DataContract]
public enum Relationship
{
Invalid = 0,
Spouse = 4,
ResidesWith = 1,
Parent = 2,
Other = 3,
PersonalGuarantor = 5,
CoApplicant = 6
}
Don't forget that enumerations are based on an integer type (their base type), so they will always have a value (value types cannot be null) and will default to 0. Making this explicit will also make things clearer in your codebase.
Protip: You can use negative values in enums as well.
I have some items in database. Each of'em can have many tags, like Browsable, or IsInMenu and so on. A friend of mine suggested to use enums with Flags attribute to create an extensible solution. So, I created a field in DB which takes an integer value, then I created this enum:
[Flags]
public enum ItemTags { Browsable = 2, IsInMenu = 4}
Now I'd like to be able to semantically get the list of some items this way:
public List<Item> GetItems(ItemTags tags)
{
/*
Code to get data from DB, something like,
return repository.GetList(tags);
*/
}
and in UI, I'd like to call:
List<Item> items = GetItems(ItemTags.Browsable | ItemTags.IsInMneu);
But I don't get the desired result. Am I going the right way?
By desired result, I mean this:
Values stored in database could be one of the 0, 2, 4, 6 values now. 0 means that the item is not in Menu and also not Browsable. 2 Means that item is Browable, but not in Menu. 4 means item is in Menu, but not Browsable. 6 means item is both Browsable and IsInMenu. Now when I call GetItems function, I don't get all the items which are browsable, in menu, or both browsable and in menu.
You need to use FlagsAttribute, see this MSDN article, and this usage example, and most importantly this stack overflow answer.
use the FlagsAttribute Class
Indicates that an enumeration can be
treated as a bit field; that is, a set
of flags.
[Flags]
public enum ItemTags
{
Default =0,
Browsable = 2,
IsInMenu = 4,
All = 6 // Browsable / IsInMenu
}
More here
note about enums:
an Enum by default has an int
underneath, and as do all integers
in C# an enum has a default value of 0
when first created. So if 0 is not
mapped to an enumeration constant
then your enum will be instantiated
with an invalid valid
You are missing the Flags attribute...
Your enum should be declared like this:
[Flags]
public enum ItemTags { Browsable = 2, IsInMenu = 4}
EDIT:
After your update, it looks fine. You should be more precise in what you mean with:
But I don't get the desired result.
The code you showed us looks fine. So either there is a problem elsewhere or the code you really use in your application and the code you showed us here are different.
This question already has answers here:
Get enum from enum attribute
(7 answers)
Closed 9 years ago.
This may seem a little upside down faced, but what I want to be able to do is get an enum value from an enum by its Description attribute.
So, if I have an enum declared as follows:
enum Testing
{
[Description("David Gouge")]
Dave = 1,
[Description("Peter Gouge")]
Pete = 2,
[Description("Marie Gouge")]
Ree = 3
}
I'd like to be able to get 2 back by supplying the string "Peter Gouge".
As a starting point, I can iterate through the enum fields and grab the field with the correct attribute:
string descriptionToMatch = "Peter Gouge";
FieldInfo[] fields = typeof(Testing).GetFields();
foreach (FieldInfo field in fields)
{
if (field.GetCustomAttributes(typeof(DescriptionAttribute), false).Count() > 0)
{
if (((DescriptionAttribute)field.GetCustomAttributes(typeof(DescriptionAttribute), false)[0]).Description == descriptionToMatch)
{
}
}
}
But then I'm stuck as to what to do in that inner if. Also not sure if this is the way to go in the first place.
Using the extension method described here :
Testing t = Enum.GetValues(typeof(Testing))
.Cast<Testing>()
.FirstOrDefault(v => v.GetDescription() == descriptionToMatch);
If no matching value is found, it will return (Testing)0 (you might want to define a None member in your enum for this value)
return field.GetRawConstantValue();
You could of course cast it back to Testing if required.
Ok, after typing all that I think this is a case of a decision right at the beginning leading me down the wrong path. Enum seemed the right way to go to start with, but a simple Dictionary<string, int> will suffice and be a hell of a lot easier to work with!
say I have the following declarations:
public enum Complexity { Low = 0, Normal = 1, Medium = 2, High = 3 }
public enum Priority { Normal = 1, Medium = 2, High = 3, Urgent = 4 }
and I want to code it so that I could get the enum value (not the index, like I earlier mentioned):
//should store the value of the Complexity enum member Normal, which is 1
int complexityValueToStore = EnumHelper.GetEnumMemberValue(Complexity.Normal);
//should store the value 4
int priorityValueToStore = EnumHelper.GetEnumMemberValue(Priority.Urgent);
How should this reusable function look like?
tia!
-ren
Revised answer (after question clarification)
No, there's nothing cleaner than a cast. It's more informative than a method call, cheaper, shorter etc. It's about as low impact as you could possibly hope for.
Note that if you wanted to write a generic method to do the conversion, you'd have to specify what to convert it to as well: the enum could be based on byte or long for example. By putting in the cast, you explicitly say what you want to convert it to, and it just does it.
Original answer
What do you mean by "index" exactly? Do you mean the numeric value? Just cast to int. If you mean "position within enum" you'd have to make sure the values are in numeric order (as that's what Enum.GetValues gives - not the declaration order), and then do:
public static int GetEnumMemberIndex<T>(T element)
where T : struct
{
T[] values = (T[]) Enum.GetValues(typeof(T));
return Array.IndexOf(values, element);
}
You can find the integer value of an enum by casting:
int complexityValueToStore = (int)Complexity.Normal;
The most generic way I know of is to read the value__ field using reflection.
This approach makes no assumptions about the enum's underlying type so it will work on enums that aren't based on Int32.
public static object GetValue(Enum e)
{
return e.GetType().GetField("value__").GetValue(e);
}
Debug.Assert(Equals(GetValue(DayOfWeek.Wednesday), 3)); //Int32
Debug.Assert(Equals(GetValue(AceFlags.InheritOnly), (byte) 8)); //Byte
Debug.Assert(Equals(GetValue(IOControlCode.ReceiveAll), 2550136833L)); //Int64
Note: I have only tested this with the Microsoft C# compiler. It's a shame there doesn't appear to be a built in way of doing this.
I realize this isn't what you asked, but it's something you might appreciate.
I discovered that you can find the integer value of an enum without a cast, if you know what the enum's minimum value is:
public enum Complexity { Low = 0, Normal = 1, Medium = 2, High = 3 }
int valueOfHigh = Complexity.High - Complexity.Low;
This wouldn't work with Priority, unless you added some minimal value of 0, or added 1 back:
public enum Priority { Normal = 1, Medium = 2, High = 3, Urgent = 4 }
int valueOfUrgent = Priority.Urgent - Priority.Normal + 1;
I find this technique much more aesthetically appealing than casting to int.
I'm not sure off the top of my head what happens if you have an enum based on byte or long -- I suspect that you'd get byte or long difference values.
If you want the value, you can just cast the enum to int. That would set complexityValueToStore == 1 and priorityValueToStore == 4.
If you want to get the index (ie: Priority.Urgent == 3), you could use Enum.GetValues, then just find the index of your current enum in that list. However, the ordering of the enum in the list returned may not be the same as in your code.
However, the second option kind of defeats the purpose of Enum in the first place - you're trying to have discrete values instead of lists and indices. I'd rethink your needs if that is what you want.
This is the most simple way to solve your problem:
public static void GetEnumMemberValue<T>(T enumItem) where T : struct
{
return (int) Enum.Parse(typeof(T), enumItem.ToString());
}
It works for me.