Neo Vijay
Neo Vijay

Reputation: 863

Enum Issue for same ID and different description

I am facing issue with Enum's in C#.

I have enum data with same id but different descriptions.

public enum Flags
{
    [Description("Flag Yes")]
    FlagYes=1,
    [Description("Flag No")]
    FlagNo=1,
    [Description("Item Yes")]
    ItemYes=2,
    [Description("Item No")]
    ItemNo=2,
}

Flags flag = Flags.FlagYes;
string Description = flag.Description();

I got inside Description value "Flag No" but i need "Flag Yes". Any on help me how it fix it this one?

I Used below common code for getting description from enum.

public static string Description(this Enum Value)
{
    FieldInfo field = Value.GetType().GetField(Value.ToString());
    DescriptionAttribute attribute = Attribute.GetCustomAttribute(field, typeof(DescriptionAttribute)) as DescriptionAttribute;
    return attribute == null ? Value.ToString() : attribute.Description;
}

Any solution please let me know?

Upvotes: 0

Views: 902

Answers (4)

Scrobi
Scrobi

Reputation: 1215

As others have said what you are currently doing is not possible, you cannot have two flags with the same integer value and then try and distinguish between them

An alternative is to change you enum to having additional values for grouping other values together:

public enum Flags
{
    [Description("Flag Yes")]
    FlagYes = 1,
    [Description("Flag No")]
    FlagNo = 2,
    [Description("Item Yes")]
    ItemYes = 4,
    [Description("Item No")]
    ItemNo = 8,
    IsFlag = (FlagYes | FlagNo), //group Flag values 
    IsItem = (ItemYes | ItemNo)  //group Item values
}

You can then check if the enum is a Flag or Item like this:

public bool IsFlag(Flags a)
{
    return (Flags.IsFlag.HasFlag(a));
}

public bool IsItem(Flags a)
{
    return (Flags.IsFlag.HasFlag(a));
}

Update

As others have explained the underlying type of an Enum is the int value. So even though in your code you are saying FlagYes it is the value 1 that is passed the method. Your code then looks up value 1 and finds FlagsNo. The number 1 cannot mean both FlagsYes and FlagNo.

If you need your enum to be the value 1 and 2 but also need FlagsYes and FlagsNo you have two seperate concerns and need to create a different solution.

If the value for FlagsYes and FlagsNo is arbitrary and can anything as long as they are the same then you create the group enum values as per the above code.

Upvotes: 0

Paul Karam
Paul Karam

Reputation: 4210

You have 4 values in the enum but only two "real" values.
So your posted enum in the question is actually more likely equal to this:

public enum Flags
{
    [Description("Flag No")]
    FlagNo=1,
    [Description("Item No")]
    ItemNo=2,
}

with the ability to access FlagNo and ItemNo using FlagYes and ItemYes because they are also defined, but with same value.

In order to solve your problem you have to fix your enum to look like this:

public enum Flags
{
    [Description("Flag Yes")]
    FlagYes=1,
    [Description("Flag No")]
    FlagNo=2,
    [Description("Item Yes")]
    ItemYes=3,
    [Description("Item No")]
    ItemNo=4,

}

Edit according to comments:

I got "Flag No" but i need "Flag Yes". Any on help me how it fix it this one?

To reply to your comment, if you have a really strong reason why do you want to have same ID, I suggest as well having two enum, one for the yes and one for the no, the way you have used it:

Flags flag = Flags.FlagYes;
string Description = flag.Description();

won't let the 'code' to magically know which description to give you, so if you want, here's another way to do it having same ID with two enum:

public enum YesFlags
{
    [Description("Flag Yes")]
    FlagYes=1,
    [Description("Item Yes")]
    ItemYes=2
}

public enum NoFlags
{
    [Description("Flag No")]
    FlagNo=1,
    [Description("Item No")]
    ItemNo=2
}

Then you can use the required enum with same ID.

Upvotes: 2

Georg
Georg

Reputation: 5771

An enumeration in .NET is basically an integer where the compiler helps you to ensure that it is only one of a previously selected range of constants. Because enums are value types, only the underlying number is present at runtime. There is no extra field that specifies which of the constants is meant because this is supposed to be encoded in that number.

Being numbers, however, you have all integer operations at your disposal for enumerations and that includes bitwise operations. You may have come across the | operator to combine flagged enums, but you can also use masks:

public enum Flags
{
    [Description("Flag Yes")]
    FlagYes=1,
    [Description("Flag No")]
    FlagNo=5,
    [Description("Item Yes")]
    ItemYes=2,
    [Description("Item No")]
    ItemNo=6,
    Mask=3
}

Then, you can restore your id using value & Flags.Mask. However, ItemNo and FlagNo can still be distinguished.

Upvotes: 0

adjan
adjan

Reputation: 13652

What you want is not possible. Since you have both assigned 1 to both enum entries, there is no way to distinguish between them, because internally, only the numeric values are taken into consideration.

Upvotes: 0

Related Questions