enum name with multiple values - c#

In my project i'm using enums example:
public enum NcStepType { Start = 1, Stop = 3, Normal = 2 }
i'm reading values from a database, but sometimes there are 0-values in my record, so i want an enum that looks like
public enum NcStepType { Start = 1 OR 0, Stop = 3, Normal = 2 }
is this possible (in c#) ?

You could create a generic extension method that handles unknown values:
public static T ToEnum<T>(this int value, T defaultValue)
{
if (Enum.IsDefined(typeof (T),value))
return (T) (object) value;
else
return defaultValue;
}
Then you can simply call:
int value = ...; // value to be read
NcStepType stepType = value.ToEnum(NcStepType.Start);
// if value is defined in the enum, the corresponding enum value will be returned
// if value is not found, the default is returned (NcStepType.Start)

No, basically. You would have to give it one of the values (presumably the 1), and interpret the other (0) manually.

No it is not, and I'm not sure how it would work in practice.
Can't you just add logic that maps 0 to 1 when reading from the DB?

Normally i define in such cases the 0 as follows:
public enum NcStepType
{
NotDefined = 0,
Start = 1,
Normal = 2,
Stop = 3,
}
And somewhere in code i would make an:
if(Step == NcStepType.NotDefined)
{
Step = NcStepType.Start;
}
This makes the code readable and everyone knows what happens... (hopefully)

No, in C# an enum can have only one value.
There's nothing that says the value in the database must map directly to your enum value however. You could very easily assign a value of Start whenever you read 0 or 1 from the database.

public enum NcStepType { Start = 1 | 0, Stop = 3, Normal = 2 }

No solution in C#. But you can take 2 steps:
1. Set default value of your DB field to 1.
2. Update all existing 0 to 1.

As far as I know you can write this
enum NcStepType { Start = 0, Start = 1, Stop = 3, Normal = 2 }
The only problem is later there would be no way telling which Start was used for variable initialization (it would always look like it was the Start = 0 one).

Related

Getting an Enum member by its index (not the value assigned to it) in c#

in JavaScript world you can get an enum value according to its index in the object (not the value assigned to the enum member, but always the nth member of that enum):
const myEnum = {
Hello: 1,
Bye: 2,
Greeting: 3
}
const value = myEnum[Object.keys(myEnum)[0]];
console.log(value) // it returns 1
I was wondering if it's possible to have this kind of behavior in C# too.
I am trying to find the nth member of an Enum in C# and the values in it are all different and there is no order to them (and that's exactly how I want them to be).
Update
enum CSharpEnum {
SomeValue = 4,
AnotherValue = 2,
AndAnotherOne = 1
}
I get some indexes (like n) from somewhere else and I want to get the nth memeber of CSharpEnum. An example:
var index = 2;
var member // a way to get the member and it should return 1 (AndAnotherOne)
// because it is the third member (0, 1, 2)
Update 2
It seems my question is not clear enough so here is a link to a dotnetfiddle playground.
In one of the answers there was a GetValues method which made a list of enum values but the enum members got rearranged in it.
I have an enum in the playground and I want to get the third (0, 1, 2) member for example which is Want. Is there a way I can get that?
With enum
public enum Test
{
hello,
world
}
Create an array with
var enums = (Test[])Enum.GetValues(typeof(Test));
And now it's indexable.
Given
public enum myEnum
{
Hello = 1,
Bye = 2,
Greeting = 3
}
the Enum Class has a static method GetValues(Type) that returns an array TEnum[] of the values of this enum:
myEnum[] enumArray = (myEnum[])Enum.GetValues(typeof(myEnum));
myEnum value = enumArray[i]; // { [0] = Hello, [1] = Bye, [3] = Greeting }
Newer versions of the Framework have a generic overload (since .NET Framework 5.0?):
myEnum[] enumArray = Enum.GetValues<myEnum>();
myEnum value = enumArray[i];
UPDATE
The purpose of an enumeration type is to provide a set of named constants having an underlying integral numeric type. These constants are not indexed and have no particular order defined. If you want to have them indexed, insert them into an array
enum myEnum {
SomeValue = 4,
AnotherValue = 2,
AndAnotherOne = 1
}
static readonly myEnum[] enumArray = new[] {
myEnum.SomeValue,
myEnum.AnotherValue,
myEnum.AndAnotherOne
};
myEnum value = enumArray[2]; // --> myEnum.AndAnotherOne
See also: Enumeration types (C# reference)

Increment an enumeration value to the next one

I have an enumeration like so:
[Flags]
public enum UserProcessStage : uint
{
ShopSelection = 1,
FillBasket = 2,
SpecifyShipmentCredentials = 4,
SpecifyPaymentCredentials = 8,
OrderComplete = 16
}
Assuming I have a variable whose value is FillBakset (2), what I want to do is be able to increment it to the next value that is defined within the enumeration (SpecifyShipmentCredentials, 4).
The problem is that incrementing it causes its value to be 3 since it is based on an integer, I tried multipliying it by 2 but got a compilation error.
How could I increment an enumeration value to the next one ?
Thanks
You can use this code. It basically orders the enum by underlying value and then givs you the first enum which is bigger than the one specified. If none found, it will return 0 because of DefaultIfEmty():
public static UserProcessStage GetNext(UserProcessStage value)
{
return (from UserProcessStage val in Enum.GetValues(typeof (UserProcessStage))
where val > value
orderby val
select val).DefaultIfEmpty().First();
}

Convert output of string to a number value

I have the following code
Call.Direction CallDir = details.dir;
and the output is either In or out.
my question how can I convert the output to be as follow:
if CallDir value is In ===> display 0
if CallDir value is Out ===> display 1
Okay, so if you wanted to return a different value based on the enum, just do this:
return CallDir == Call.Direction.In ? 0 : 1;
However, if what you're saying is details.dir is a string of In or Out and you need to get that into an enum, then do this:
Call.Direction CallDir;
if (!enum.TryParse<Call.Direction>(details.dir, out CallDir))
{
// set it to some default value because it failed
}
In addition to what Michael said, if your enum is defined with the appropriate values, you can simply cast it to an int.
enum CallDirection { In = 0, Out = 1 }
var dir = CallDirection.In;
Console.Write((int)dir); // "0"

How can I get the bitmask value back out of an enum with the flag attribute in C#?

In our database we have a bitmask that represents what types of actions a user can make.
In our C# client when we retrieve this integer value from the database we construct an enum/flag. It looks somewhat like the following:
[Flags]
public enum SellPermissions
{
Undefined = 0,
Buy = 1,
Sell = 2,
SellOpen = 4,
SellClose = 8
// ...
}
In our application I have an edit permissions page which I then use to modify the value of this enum using the bitwise OR on different enum values.
permissions = SellPermisions.Buy | SellPermissions.Sell;
Now, after these changes are made, in my database call I need to call an update/insert sproc which is expecting an integer value.
How do I get the integer bitwise value back out of my enum/flag so I can set the modified permissions in the database?
I was able to do it by casting the variable to an int.
int newPermissions = (int)permissions.
int permissionsValue = (int) permissions;
You can use HasFlag() like this:
SellPermissions permissions = SellPermissions.Buy | SellPermissions.Sell;
if(permissions.HasFlag(SellPermissions.Sell))
{
MessageBox.Show("You have Sell permissions");
}

C# function that accepts an Enum item and returns the enum value (not the index)

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.

Categories