Possible to load an Enum based on a string name? - c#

OK, I don't think the title says it right... but here goes:
I have a class with about 40 Enums in it. i.e:
Class Hoohoo
{
public enum aaa : short
{
a = 0,
b = 3
}
public enum bbb : short
{
a = 0,
b = 3
}
public enum ccc : short
{
a = 0,
b = 3
}
}
Now say I have a Dictionary of strings and values, and each string is the name of above mentioned enums:
Dictionary<string,short>{"aaa":0,"bbb":3,"ccc":0}
I need to change "aaa" into HooBoo.aaa to look up 0. Can't seem to find a way to do this since the enum is static. Otherwise I'll have to write a method for each enum to tie the string to it. I can do that but thats mucho code to write.
Thanks,
Cooter

You'll have to use Reflection to get the underlying enum type:
Type t = typeof(Hoohoo);
Type enumType = t.GetNestedType("aaa");
string enumName = Enum.GetName(enumType, 0);
If you want to get the actual enum value, you can then use:
var enumValue = Enum.Parse(enumName, enumType);

Use
aaa myEnum =(aaa) Enum.Parse(typeof(aaa), "a");

You want to convert a string -> enum? This should help.

Just keep in mind that Enum.Parse isn't strongly typed... I reckon that will be a real limitation in your scenario. As you can see from Ngu's example you'd have to cast the output.

Related

Is there a type that is the opposite of an enum?

For example, here is a simple enum:
enum Something {
One = 1,
Two = 2,
Three = 3
}
But I would like to create the opposite of this code, like
SomeType Something {
1 = One,
2 = Two,
3 = Threee
}
Maybe I could introduce constants, like
static class Something {
public const 1 = "One";
// ...
}
but I get compiler errors (CS1031, CS1001, CS0145 and CS1003), because c# can't handle this.
I can do the same with enums to prevent these unnecessary errors, but here I also get CS1001, because c# does not undertand that the numbers are the identifiers.
I can also use strings, but this makes it even more complicated, because c# expects another identifier for them (but doesn't accept one (CS0029))
So, is there anything in c# that can be used to assign some string-like values to numbers as constants or like enums?
You can not have numeric value as your variable name, So to solve this issue you can create a Dictionary of key integer and value as string like this Dictionary<int, string> and use it accordingly.
If that's how to use the enum name, you can use Enum.TryParse<someEnumTyme>(someString, out _someEnumVar).
But the Dictionary solution of is more elegant in my opinion.
At runtime, for many operations, using an enum variable is the same as using the underlying type.
enum Something {
One = 1,
Two = 2,
Three = 3
}
Something foo = Something.One; // assign 1 to foo
You can use the definition of an enum to create a mapping between values and names;
var lookup = ((Something[])Enum.GetValues(typeof(Something)))
.ToDictionary(e => e.ToString(), e => (int)e);

Retrieving integer values from an enum

I have defined an enum and tried to retrieve it as follows
class Demo
{
enum hello
{
one=1,
two
}
public static void Main()
{
Console.WriteLine(hello.one);
Console.ReadLine();
}
}
Now, how do i retrieve the integer value "1" from the enum ?
There's an explicit conversion from any enum type to its underlying type (int in this case). So:
Console.WriteLine((int) hello.one);
Likewise there's an explicit conversion the other way:
Console.WriteLine((hello) 1); // Prints "one"
(As a side note, I'd strongly advise you to follow .NET naming conventions, even when writing tiny test apps.)
you can cast the enums like
int a = (int)hello.one
Well you can do a cast to int
Console.WriteLine((int)hello.one);
Try This.
Console.Writeline((int)hello.Value);
or
int value = Convert.ToInt32(hello.one);

Do enums need an index?

I have a number of enums that contain long lists that do change from time to time
public MyEnumType MyEnum
{
None = 0,
Option1 = 1,
Option2 = 2,
etc..
}
When they change, I need to renumber the index as invariably new options are placed inbetween existing options.
The question is, if I remove the index, will the enum always honour the order from top to bottom?
public MyEnumType MyEnum
{
None,
Option1,
Option2,
etc..
}
Thanks in advance.
Yes they will.
You can also specify just the first element if you want to make sure that values start at some specific value:
public MyEnumType MyEnum
{
None = 1,
Option1, // -> 2
Option2, // -> 3
}
For other details, check the docs.
Note that in most scenarios, your code should not care about the exact numeric values.
Situations when you do care are e.g. if you declare an enum which is an alias for an external type (e.g interop) so you need to ensure that values are the same. Another scenario is when the enumeration represents binary flags, then you want something like:
[Flags]
public MyEnumType MyEnum
{
None = 1,
Option1 = 2,
Option2 = 4
}
Simplest answer would be "Yes"... they will always honor the order.
So you no need to put index number.
public MyEnumType MyEnum
{
None,
OptionA,
OptionB,
OptionC,
...
...
OptionZ
}
this will always same as -
public MyEnumType MyEnum
{
None = 0,
OptionA = 1,
OptionB = 2,
OptionC = 3,
...
...
OptionZ = 26
}
If you introduce new enum type in between like -
public MyEnumType MyEnum
{
None,
OptionA,
OptionB,
OptionC,
...
...
OptionO
OptionNew
OptionP
...
...
OptionZ
}
Then above will be equivalent to -
public MyEnumType MyEnum
{
None = 0,
OptionA = 1,
OptionB = 2,
OptionC = 3,
...
...
OptionO = 15
OptionNew = 16
OptionP = 17
...
...
OptionZ = 27
}
Yes they honour the order, starting from the default value for int, which is zero.
If you are regularly renumbering things then it is better to explicitly assign values to the enum members, and then re-number the items when the underlying list that it is based on changes.
If you use explicit numbering then you can also insert new items into the list between existing items at any time, although you do need to be careful that you don't assign two items to the same value (which is totally legal in C#, but may produce errors if you didn't intend it).
From the C# language specification 1.10 Enums:
... When an enum member declaration does not explicitly specify a value,
the member is given the value zero (if it is the first member in the
enum type) or the value of the textually preceding enum member plus
one.
So the same as your explicit declaration here:
public MyEnumType MyEnum
{
None = 0,
Option1 = 1,
Option2 = 2,
etc..
}
By default they will count up from zero in the order they are declared.
If you define one explicitly, then the subsequent values continue counting up, using the explicit value as a seed.

Convert CSV from enum flags and vice versa

Consider the following enum:
[Flags]
public enum MyEnum
{
Option1 = 0,
Option2 = 1,
Option3 = 2,
Option4 = 4
}
Is there a way in which I can get the string equivalent (not the value) as a CSV string? Normally I can use the Enum.GetName function to convert a type to the string representation, however, if you use a combination this returns null.
So basically I would like to convert:
var options = MyEnum.Option1 | MyEnum.Option3;
into
"Option1, Option3"
Then I would like to be able to convert "Option1, Option3" back to MyEnum.Option1 | MyEnum.Option2.
Suggestions?
Well, aside from Option1 not making much sense in a flags enum, this just works by default using Enum.Parse and Enum.ToString().
Start with this:
var options = MyEnum.Option2 | MyEnum.Option3;
Console.WriteLine(options.ToString());
// Outputs: Option2, Option3
Then you can always do this:
var options2 = (MyEnum) Enum.Parse(typeof (MyEnum), "Option2, Option3");
Now try this:
Console.WriteLine((options2 & MyEnum.Option2) == MyEnum.Option2);
Console.WriteLine((options2 & MyEnum.Option4) == MyEnum.Option4);
// Outputs:
// true
// false
Which seems like it does exactly what you wanted (again, ignoring the fact that Option1 in your example will never occur)
docs: Enum.Parse
You could do a Enum.GetValues which gets an array of enum values. You can then loop through those values and test them against your Enum value, concatenating the string value for each one that matches. The other way around you can loop through the values using the Enum.GetName function to test if your string contains that values name and then rebuild the value.

How do I change the type of an enum?

By default, C# enums are stored as integers. I'd like to make it a short instead. Is there a way to do this?
sure, this can be done, but it has to be an integral type ( byte, short, int, etc.) except char...
enum myEnum : short
{
FirstValue = 0,
};
here is the MSDN docs
Like this:
enum MyEnum : short
{
...
}
Sometimes it makes more sense to have String values as enums you can use Attributes and achieve this check this link http://weblogs.asp.net/stefansedich/archive/2008/03/12/enum-with-string-values-in-c.aspx
yes you can create enum like
enum Range : short {Max = 6, Min = 1, Mid = 3};

Categories

Resources