I'm using Matlab R2010b and I've got an enum under C# :
[Flags()]
public enum MyFormat
{
value1 = 0,
value2 = 1,
value3 = 2,
value4 = 4,
value5 = 8
}
In a method, I've got an argument which is a format :
public void MyMethod(MyFormat format, double number)
{
....
}
Then I work with Matlab, and I want to use the method MyMethod. In a standard way, here is the code :
>>format = MyNamespace.MyFormat.value1;
>>MyNamespace.MyMethod(format, 15);
The issue comes when I try to pass a "multiple value" as a MyFormat :
>>format = MyNamespace.MyFormat.value1 | MyNamespace.MyFormat.value2;
>>MyNamespace.MyMethod(format, 15);
I found a easy solution but it takes a more recent version of Matlab R2011a. Another solution found here was to implement this function in Matlab :
function enum = EnumParse(typename, value)
type = System.Type.GetType(typename);
values = regexp(value, ', ', 'split');
enum = cell(1, length(values));
for i = 1:length(values)
enum{i} = System.Enum.Parse(type, values{i});
end
end
However, the line System.Type.GetType('MyNamespace.MyFormat') returns me a null value, whereas it is not null with a type System.Type.GetType('System.String') for example.
My question is then how to parse multiple values to an enum ?
Thanks !
Does MatLab, for it's Enum.Parse take any multiple overloads for example
type, value, value ...?
Related
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)
This question already has answers here:
Create instance of unknown Enum with string value using reflection in C#
(2 answers)
Closed 3 years ago.
What I have is a string variable that is the name of a enum. I have the integer of the enum. How would I convert that into instance of the enum itself?
Enum TestEnum
{
One = 1,
Two = 2,
Three = 3
}
string str = "TestEnum";
int intValue = 2;
I see many posts that require you to have an instance of the enum to get it's like this highly upvoted answer.
I need to do this at runtime.
Edit:
I am trying to write a class that gets and sets settings in an api that has hundreds of enums that represent settings.
The enums break are categorized by 5 basic setting types represented by five enums. These enums are like:
DoubleValueEnum
IntegerValueEnum
BooleanValueEnum
StringValueEnum
These enums are pointers to settings of type double, integer, string, bool. I believe that underneath the hood they have a database that keeps a table like this:
Type key value Represents
------- ------ ------- ---------------------------------
Double 23 2.745 DoubleValueEnum.DrawingWidth
Integer 5 18 IntegerValueEnum.PenColor
Double 54 15.9245 DoubleValueEnum.GridMajorSpacing
For doubles there is no "lower" enum that it is pointing to. For integer there is a deeper enum like "PenNumber.Red = 1, PenColor.Green = 2.
Hypothetical pen color:
Enum PenColor
{
Red = 1,
Blue = 2,
}
Each of these enums have hundreds of values. Each of these enums has a prewritten function the gets or sets the enum:
GetDoubleEnumValue(int, option)
GetIntegerValueEnum(int, option)
GetBooleanValueEnum(int, option)
GetStringValueEnum(int, option)
SetXXXXXEnumValue(enum, value)
SetDoubleEnumValue(int, int)
SetIntegerValueEnum(int, int)
SetBooleanValueEnum(int, int)
SetStringValueEnum(int, int)
Real example:
SetIntegerValueEnum ((int)IntegerValueEnum.swDxfVersion, (int)swDxfFormat_e.swDxfFormat_R14);
For your given enum definition:
enum TestEnum
{
One = 1,
Two = 2,
Three = 3
}
enum TestEnum2
{
OnePoint1 = 1,
OnePoint2 = 2,
OnePoint3 = 3
}
Use Enum.Parse(Type, string) to parse the string value as an Enum value.
string str = "Two";
TestEnum valueAsEnum = (TestEnum)Enum.Parse(typeof(TestEnum), str);
However, you need to know they type of the Enum definition that you want to parse. If the exact type of the enum value is unknown, but you do know the potential types, then you can iterate through the types and test using the Enum.TryParse
string str = "Two";
object enumValue = null;
if (!Enum.TryParse(typeof(TestEnum), str, true, out enumValue))
Enum.TryParse(typeof(TestEnum2), str, true, out enumValue))
If you do not know the specific type of the enum but you do know the class name, you can use the Type.GetType Method to resolve the type
For this to work you do need to know the full namespace of type that you want to resolve, AND the assembly that the type is defined in must already be loaded.
The syntax to convert an int to an enum is discussed here: https://stackoverflow.com/a/56859286/1690217
In this example, we know that all of the enums reside in the API.Client.Enums namespace:
string str = "TestEnum";
int intValue = 2;
string ns = "API.Client.Enums";
Type enumType = Type.GetType($"{ns}.{str}");
// now we can parse the value:
object value = Enum.ToObject(enumType, (object)intValue);
Usually we do not need to bother with a lot of this conversion just to pass values between systems, the fact that the enum resolves to an integer means that for unknown types we should be able to write our logic to just deal with the integer, and only convert it back to a specific enum when you need it.
It looks like you are trying to use BitWise operations on Enum values to allow a single setting property to represent multiple optional states.
For this sir Enums have support built in if you use the Flags attribute:
There is a good SO dicussion that covers this too: What does the [Flags] Enum Attribute mean in C#?
Lets look at PenColor enum first:
[Flag]
enum PenColor : int
{
None = 0 // 0
Red = 1 << 0, // 1
Green = 1 << 1, // 2
Blue = 1 << 2 // 4
}
By defining the discrete enums with base-2 values, we can now use either bitwise operations on the PenColor enum, or we can use simple integer addition/subtraction:
PenColor cyan = PenColor.Green | PenColor.Blue;
int cyanInt = (int)PenColor.Green + (int)PenColor.Blue;
PenColor cyanCasted = (PenColor)cyanInt;
All of those statements will be equivalent. So potentially this syntax replaces your SetIntegerValueEnum, but it relies on the enum definition being implemented with base-2 values.
To test, this statement should be true:
SetIntegerValueEnum ((int)IntegerValueEnum.swDxfVersion, (int)swDxfFormat_e.swDxfFormat_R14)
== (int)IntegerValueEnum.swDxfVersion + (int)swDxfFormat_e.swDxfFormat_R14)
== IntegerValueEnum.swDxfVersion | swDxfFormat_e.swDxfFormat_R14
The last option will only work if the [Flags] attribute decorates the enum type definition.
You can then use this in switching logic or comparisons
PenColor cyan = PenColor.Green | PenColor.Blue;
bool hasBlue = cyan & PenColor.Blue == PenColor.Blue;
// you can also use the slower Enum.HasFlag
hasBlue = cyan.HasFlag(PenColor.Blue);
I need to convert a List of enums values to a single string to store in my db; then convert back again when I retrieve from the database.
Each enum's value is currently a simple integer, so it feels a bit overkill to create an extra table to deal with this.
So, in the example below, if the user selects Mother, Father and Sister, then the value stored in the database will be "0,1,3"
public enum MyEnum
{
Mother = 0,
Father = 1,
Gran = 2,
Sister = 3,
Brother = 4
}
I'm new to c#, so not sure if there is a nice out-the-box way to do this - I couldn't find anything obvious when google hunting!
Cheers in advance :)
- L
Enum's are explicitely able to be cast to/from integers
int value = (int)MyEnum.Mother;
and
MyEnum value = (MyEnum)1;
For strings use ToString and Enum.Parse
string value = MyEnum.Mother.ToString();
and
MyEnum value = (MyEnum)Enum.Parse(typeof(MyEnum),"Mother");
If you change you enum values to:
[Flags]
public enum MyEnum
{
Mother = 1,
Father = 2,
Gran = 4,
Sister = 8,
Brother = 16,
}
Then you could store Father and Gran as 6
Sister and Brother as 24 etc
by using binary numbers you should not get duplicate values by combining them
The following will convert back and forth between an array of Enum values via "0,1,3" as requested:
MyEnum[] selection = { MyEnum.Mother, MyEnum.Father, MyEnum.Sister };
string str = string.Join(",", selection.Cast<int>());
MyEnum[] enm = str.Split(',').Select(s => int.Parse(s)).Cast<MyEnum>().ToArray();
from your code it is
MyEnum a = MyEnum.Mother;
string thestring = a.ToString();
MyEnum b = (MyEnum) Enum.Parse(typeof(MyEnum), thestring);
Just use ToString to convert to the name, and the use Enum.TryParse (or Enum.Parse if you're not on .NET 4) to convert back.
If you're wanting one enum field to contain multiple values (e.g MyEnum.Mother | MyEnum.Father), you'll need to convert that to a Flags enum, as #WraithNath suggested. Otherwise you're talking about storing each option separately (there's no way to store Mother and Father in the same field with your current setup).
String Equivelant
MyEnum value = MyEnum.Father;
value.ToString(); // prints Father
Parsing
(MyEnum)Enum.Parse(typeof(MyEnum), "Father"); // returns MyEnum.Father
Enums can be cast to and from integer values. That's probably your best bet.
If you really want to use strings, ToString will return "Mother" "Father" "Gran" etc. Casting back from a string would just be a function:
private MyEnum GetEnumValue(string fromDB)
{
if( fromDB == "Mother" ) return MyEnum.Mother;
else if( fromDB == "Father") return MyEnum.Father;
//etc. etc.
}
EDIT:
Ian's answer for casting back is the more "C#-ey" way of doing it, and is far more extensible (handles adding new values to the enum much more flexibly).
Further to Jamiec's suggestion (which fits well for your need), if you need to defensively code your casting, try:
if (Enum.IsDefined(typeof(MyEnum), <your database value>))
{
// Safe to convert your enumeration at this point:
MyEnum value = (MyEnum)1;
}
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).
How do you get the max value of an enum?
Enum.GetValues() seems to return the values in order, so you can do something like this:
// given this enum:
public enum Foo
{
Fizz = 3,
Bar = 1,
Bang = 2
}
// this gets Fizz
var lastFoo = Enum.GetValues(typeof(Foo)).Cast<Foo>().Last();
Edit
For those not willing to read through the comments: You can also do it this way:
var lastFoo = Enum.GetValues(typeof(Foo)).Cast<Foo>().Max();
... which will work when some of your enum values are negative.
I agree with Matt's answer. If you need just min and max int values, then you can do it as follows.
Maximum:
Enum.GetValues(typeof(Foo)).Cast<int>().Max();
Minimum:
Enum.GetValues(typeof(Foo)).Cast<int>().Min();
According to Matt Hamilton's answer, I thought on creating an Extension method for it.
Since ValueType is not accepted as a generic type parameter constraint, I didn't find a better way to restrict T to Enum but the following.
Any ideas would be really appreciated.
PS. please ignore my VB implicitness, I love using VB in this way, that's the strength of VB and that's why I love VB.
Howeva, here it is:
C#:
static void Main(string[] args)
{
MyEnum x = GetMaxValue<MyEnum>(); //In newer versions of C# (7.3+)
MyEnum y = GetMaxValueOld<MyEnum>();
}
public static TEnum GetMaxValue<TEnum>()
where TEnum : Enum
{
return Enum.GetValues(typeof(TEnum)).Cast<TEnum>().Max();
}
//When C# version is smaller than 7.3, use this:
public static TEnum GetMaxValueOld<TEnum>()
where TEnum : IComparable, IConvertible, IFormattable
{
Type type = typeof(TEnum);
if (!type.IsSubclassOf(typeof(Enum)))
throw new
InvalidCastException
("Cannot cast '" + type.FullName + "' to System.Enum.");
return (TEnum)Enum.ToObject(type, Enum.GetValues(type).Cast<int>().Last());
}
enum MyEnum
{
ValueOne,
ValueTwo
}
VB:
Public Function GetMaxValue _
(Of TEnum As {IComparable, IConvertible, IFormattable})() As TEnum
Dim type = GetType(TEnum)
If Not type.IsSubclassOf(GetType([Enum])) Then _
Throw New InvalidCastException _
("Cannot cast '" & type.FullName & "' to System.Enum.")
Return [Enum].ToObject(type, [Enum].GetValues(type) _
.Cast(Of Integer).Last)
End Function
This is slightly nitpicky but the actual maximum value of any enum is Int32.MaxValue (assuming it's a enum derived from int). It's perfectly legal to cast any Int32 value to an any enum regardless of whether or not it actually declared a member with that value.
Legal:
enum SomeEnum
{
Fizz = 42
}
public static void SomeFunc()
{
SomeEnum e = (SomeEnum)5;
}
After tried another time, I got this extension method:
public static class EnumExtension
{
public static int Max(this Enum enumType)
{
return Enum.GetValues(enumType.GetType()).Cast<int>().Max();
}
}
class Program
{
enum enum1 { one, two, second, third };
enum enum2 { s1 = 10, s2 = 8, s3, s4 };
enum enum3 { f1 = -1, f2 = 3, f3 = -3, f4 };
static void Main(string[] args)
{
Console.WriteLine(enum1.one.Max());
}
}
Use the Last function could not get the max value. Use the "max" function could. Like:
class Program
{
enum enum1 { one, two, second, third };
enum enum2 { s1 = 10, s2 = 8, s3, s4 };
enum enum3 { f1 = -1, f2 = 3, f3 = -3, f4 };
static void Main(string[] args)
{
TestMaxEnumValue(typeof(enum1));
TestMaxEnumValue(typeof(enum2));
TestMaxEnumValue(typeof(enum3));
}
static void TestMaxEnumValue(Type enumType)
{
Enum.GetValues(enumType).Cast<Int32>().ToList().ForEach(item =>
Console.WriteLine(item.ToString()));
int maxValue = Enum.GetValues(enumType).Cast<int>().Max();
Console.WriteLine("The max value of {0} is {1}", enumType.Name, maxValue);
}
}
In agreement with Matthew J Sullivan, for C#:
Enum.GetValues(typeof(MyEnum)).GetUpperBound(0);
I'm really not sure why anyone would want to use:
Enum.GetValues(typeof(MyEnum)).Cast<MyEnum>().Last();
...As word-for-word, semantically speaking, it doesn't seem to make as much sense? (always good to have different ways, but I don't see the benefit in the latter.)
There are methods for getting information about enumerated types under System.Enum.
So, in a VB.Net project in Visual Studio I can type "System.Enum." and the intellisense brings up all sorts of goodness.
One method in particular is System.Enum.GetValues(), which returns an array of the enumerated values. Once you've got the array, you should be able to do whatever is appropriate for your particular circumstances.
In my case, my enumerated values started at zero and skipped no numbers, so to get the max value for my enum I just need to know how many elements were in the array.
VB.Net code snippets:
'''''''
Enum MattType
zerothValue = 0
firstValue = 1
secondValue = 2
thirdValue = 3
End Enum
'''''''
Dim iMax As Integer
iMax = System.Enum.GetValues(GetType(MattType)).GetUpperBound(0)
MessageBox.Show(iMax.ToString, "Max MattType Enum Value")
'''''''
I used the following when I needed the min and max values of my enum.
I just set a min equal to the lowest value of the enumeration and a max equal to the highest value in the enumeration as enum values themselves.
public enum ChannelMessageTypes : byte
{
Min = 0x80, // Or could be: Min = NoteOff
NoteOff = 0x80,
NoteOn = 0x90,
PolyKeyPressure = 0xA0,
ControlChange = 0xB0,
ProgramChange = 0xC0,
ChannelAfterTouch = 0xD0,
PitchBend = 0xE0,
Max = 0xE0 // Or could be: Max = PitchBend
}
// I use it like this to check if a ... is a channel message.
if(... >= ChannelMessageTypes.Min || ... <= ChannelMessages.Max)
{
Console.WriteLine("Channel message received!");
}
In F#, with a helper function to convert the enum to a sequence:
type Foo =
| Fizz = 3
| Bang = 2
// Helper function to convert enum to a sequence. This is also useful for iterating.
// stackoverflow.com/questions/972307/can-you-loop-through-all-enum-values-c
let ToSeq (a : 'A when 'A : enum<'B>) =
Enum.GetValues(typeof<'A>).Cast<'B>()
// Get the max of Foo
let FooMax = ToSeq (Foo()) |> Seq.max
Running it...
> type Foo = | Fizz = 3 | Bang = 2
> val ToSeq : 'A -> seq<'B> when 'A : enum<'B>
> val FooMax : Foo = Fizz
The when 'A : enum<'B> is not required by the compiler for the definition, but is required for any use of ToSeq, even by a valid enum type.
It is not usable in all circumstances, but I often define the max value myself:
enum Values {
one,
two,
tree,
End,
}
for (Values i = 0; i < Values.End; i++) {
Console.WriteLine(i);
}
var random = new Random();
Console.WriteLine(random.Next((int)Values.End));
Of course this won't work when you use custom values in an enum, but often it can be an easy solution.