Given an arbitrary enumeration in C#, how do I select a random value?
(I did not find this very basic question on SO. I'll post my answer in a minute as reference for anyone, but please feel free to post your own answer.)
Array values = Enum.GetValues(typeof(Bar));
Random random = new Random();
Bar randomBar = (Bar)values.GetValue(random.Next(values.Length));
Use Enum.GetValues to retrieve an array of all values. Then select a random array item.
static Random _R = new Random ();
static T RandomEnumValue<T> ()
{
var v = Enum.GetValues (typeof (T));
return (T) v.GetValue (_R.Next(v.Length));
}
Test:
for (int i = 0; i < 10; i++) {
var value = RandomEnumValue<System.DayOfWeek> ();
Console.WriteLine (value.ToString ());
}
->
Tuesday
Saturday
Wednesday
Monday
Friday
Saturday
Saturday
Saturday
Friday
Wednesday
Here's an alternative version as an Extension Method using LINQ.
using System;
using System.Linq;
public static class EnumExtensions
{
public static Enum GetRandomEnumValue(this Type t)
{
return Enum.GetValues(t) // get values from Type provided
.OfType<Enum>() // casts to Enum
.OrderBy(e => Guid.NewGuid()) // mess with order of results
.FirstOrDefault(); // take first item in result
}
}
public static class Program
{
public enum SomeEnum
{
One = 1,
Two = 2,
Three = 3,
Four = 4
}
public static void Main()
{
for(int i=0; i < 10; i++)
{
Console.WriteLine(typeof(SomeEnum).GetRandomEnumValue());
}
}
}
Two
One
Four
Four
Four
Three
Two
Four
One
Three
You could just do this:
var rnd = new Random();
return (MyEnum) rnd.Next(Enum.GetNames(typeof(MyEnum)).Length);
No need to store arrays
Adapted as a Random class extension:
public static class RandomExtensions
{
public static T NextEnum<T>(this Random random)
{
var values = Enum.GetValues(typeof(T));
return (T)values.GetValue(random.Next(values.Length));
}
}
Example of usage:
var random = new Random();
var myEnumRandom = random.NextEnum<MyEnum>();
Call Enum.GetValues; this returns an array that represents all possible values for your enum. Pick a random item from this array. Cast that item back to the original enum type.
The modern answer combining this answer and its comment:
public static class RandomExtensions
{
private static Random Random = new Random();
public static T GetRandom<T>() where T : struct, Enum
{
T[]? v = Enum.GetValues<T>();
return (T)v.GetValue(Random.Next(v.Length));
}
}
Here is a generic function for it.
Keep the RNG creation outside the high frequency code.
public static Random RNG = new Random();
public static T RandomEnum<T>()
{
Type type = typeof(T);
Array values = Enum.GetValues(type);
lock(RNG)
{
object value= values.GetValue(RNG.Next(values.Length));
return (T)Convert.ChangeType(value, type);
}
}
Usage example:
System.Windows.Forms.Keys randomKey = RandomEnum<System.Windows.Forms.Keys>();
A lot of these answers are pretty old and - correct me if I'm wrong - seem to work with some sketchy concepts like type erasure and dynamic type casting. However, as user Yarek T points out, there's no need for that with the generic overload of Enum.GetValues:
static Random random = new Random();
// Somewhat unintuitively, we need to constrain the type parameter to
// both struct *and* Enum - struct is required b/c the type can't be
// nullable, and Enum is required b/c GetValues expects an Enum type.
// You'd think that Enum itself would satisfy the non-nullable
// constraint, but alas, me compiler tells me otherwise - perhaps
// someone more knowledgeable can explain why this is in a comment?
static TEnum RandomEnumValue<TEnum>() where TEnum : struct, Enum
{
TEnum[] vals = Enum.GetValues<TEnum>();
return vals[random.Next(vals.Length)];
}
Or, like in borja garcia's answer, we can even write this as an extension of the random class
public static class RandomExtensions
{
public static TEnum NextEnumValue<TEnum>(this Random random)
where TEnum : struct, Enum
{
TEnum[] vals = Enum.GetValues<TEnum>();
return vals[random.Next(vals.Length)];
}
}
And we can run the same test from mafu's answer:
Random random = new Random();
for (int i = 0; i < 10; i++) {
var day = random.NextEnumValue<System.DayOfWeek>();
Console.WriteLine(day.ToString());
}
Potential output:
Thursday
Saturday
Sunday
Sunday
Sunday
Saturday
Wednesday
Monday
Wednesday
Thursday
Personally, I'm a fan of extension methods, so I would use something like this (while not really an extension, it looks similar):
public enum Options {
Zero,
One,
Two,
Three,
Four,
Five
}
public static class RandomEnum {
private static Random _Random = new Random(Environment.TickCount);
public static T Of<T>() {
if (!typeof(T).IsEnum)
throw new InvalidOperationException("Must use Enum type");
Array enumValues = Enum.GetValues(typeof(T));
return (T)enumValues.GetValue(_Random.Next(enumValues.Length));
}
}
[TestClass]
public class RandomTests {
[TestMethod]
public void TestMethod1() {
Options option;
for (int i = 0; i < 10; ++i) {
option = RandomEnum.Of<Options>();
Console.WriteLine(option);
}
}
}
You can also cast a random value:
using System;
enum Test {
Value1,
Value2,
Value3
}
class Program {
public static void Main (string[] args) {
var max = Enum.GetValues(typeof(Test)).Length;
var value = (Test)new Random().Next(0, max - 1);
Console.WriteLine(value);
}
}
But you should use a better randomizer like the one in this library of mine.
I generate dynamic enums that represent integer IDs from my database in a C# ASP.NET solution. I would like two things, although neither may be possible.
1) I want the .ToString() method to give me "345" for example, not the string name of the enum (the int it represents as a string). Every answer to this question seems to be adding
[Description="Blah"]
EnumName = 1
above the declaration and using a GetDescription() method. I have no idea how to do this with the dynamic code that I am using.
2) I'd rather not cast to an int to use it as such, I'd rather (Enum.Name == 5) for example. If this isn't possible I'll cast, but I really don't want to use ((int)Enum.Name)).ToString();
Here's the dynamic code generation:
public static void Main()
{
AppDomain domain = AppDomain.CurrentDomain;
AssemblyName aName = new AssemblyName("DynamicEnums");
AssemblyBuilder ab = domain.DefineDynamicAssembly(aName, AssemblyBuilderAccess.Save);
ModuleBuilder mb = ab.DefineDynamicModule(aName.Name, aName.Name + ".dll");
List<Type> types = new List<Type>();
foreach(ReferenceType rt in GetTypes())
{
EnumBuilder eb = mb.DefineEnum(rt.Name, TypeAttributes.Public, typeof(int));
foreach (Reference r in GetReferences(rt.ID))
{
eb.DefineLiteral(NameFix(r.Name), r.ID);
}
types.Add(eb.CreateType());
}
ab.Save(aName.Name + ".dll");
foreach (Type t in types)
{
foreach (object o in Enum.GetValues(t))
{
Console.WriteLine("{0}.{1} = {2}", t, o, ((int) o));
}
Console.WriteLine();
//Console.ReadKey();
}
Console.WriteLine();
Console.WriteLine("Dynamic Enums Built Successfully.");
}
public static string NameFix(string name)
{
//Strip all non alphanumeric characters
string r = Regex.Replace(name, #"[^\w]", "");
//Enums cannot begin with a number
if (Regex.IsMatch(r, #"^\d"))
r = "N" + r;
return r;
}
There may just be no way to do what I want to do, and I'll be stuck using:
(int)Countries.USA //For int value
((int)Countries.CAN).ToString() //For string representation of int value, ex. "354"
Any ideas?
Could you adapt the type-safe enum pattern to do what you need?
public class MyEnum
{
#region Enum Values
// Pre defined values.
public static readonly MyEnum ValueOne = new MyEnum(0);
public static readonly MyEnum ValueTwo = new MyEnum(1);
// All values in existence.
private static readonly Dictionary<int, MyEnum> existingEnums = new Dictionary<int, MyEnum>{{ValueOne.Value, ValueOne}, {ValueTwo.Value, ValueTwo}};
#endregion
#region Enum Functionality
private readonly int Value;
private MyEnum(int value)
{
Value = value;
}
public static MyEnum GetEnum(int value)
{
// You will probably want to make this thread-safe.
if (!existingEnums.ContainsKey(value)) existingEnums[value] = new MyEnum(value);
return existingEnums[value];
}
public override string ToString()
{
return Value.ToString();
}
#endregion
}
Usage:
private void Foo(MyEnum enumVal)
{
return "Enum Value: " + enumVal; // returns "Enum Value: (integer here)
}
Or:
MyEnum.GetValue(2) == MyEnum.GetValue(4); // false
MyEnum.GetValue(3) == MyEnum.GetValue(3); // true
So you actually want to convert the Enum value to a string not the name? Casting to the Enum's underlying type is the simplest way to get the value out. I think you will struggle to get anything shorter or simpler than ((int)...).
If you don't want to "enumerate" some values, or want to do somthing different you could make your own class of YourEnum which basically has the cast built in, casting when required seems easier and more readable.
Perhaps you actually want some constants.
const string Blah = "345";
EDIT
I had another idea, you could write an extension method for Enum like this,
public static class MyExtentions
{
public static string ValueString(this Enum e)
{
var ut = Enum.GetUnderlyingType(e.GetType());
var castToString = typeOf(MyExtentions).GetMethod("CastToString");
var gcast = cast.MakeGenericMethod(ut);
var gparams = new object[] {e};
return gcast.Invoke(null, gparams).ToString();
}
public static string CastToString<T>(object o)
{
return ((T)o).ToString();
}
}
With this you can call ValueString() on any Enum instance and get a string of the value. It clearly used reflection so the performance won't be amazing but I don't think that matters in your case.
As you're using the Enum class type, how about using the Enum.Format method.
For example:
enum EnumClassA {One, Two, Three, Four};
...
EnumClassA chosenValue = EnumClassA.Three;
Console.WriteLine("Chosen value is {0}", Enum.Format(typeof(EnumClassA), chosenValue, "d"));
This should give an output of:
Chosen value is 2
edit
Another option would be:
EnumClassA.Three.ToString("d"); //Enum.Name.ToString("d")
This also gives a string value of "2".
** edit **
As you're doing comparisons to see if the value exists within your enums how about using Enum.IsDefined(enumType, value) which returns a bool?
Console.WriteLine("Does the enumClassA contain {0} result is {1}", 5, Enum.IsDefined(typeof(enumClassA), 5));
This gives an output of:
Does the enumClassA contain 5 result is False
I realise that the question has been marked as answered, but perhaps using an extension might be useful?
It still allows you to use your generated enums this way.
ps. Take care when calling GetString - don't accidentally call ToString instead!
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using System.Reflection.Emit;
namespace ConsoleApplication1
{
public enum YourEnum
{
Apples = 1,
Pears = 2,
}
class Program
{
static void Main(string[] args)
{
foreach (var value in (YourEnum[])Enum.GetValues(typeof(YourEnum)))
{
int v = value.GetValue();
Console.WriteLine("{0} = {1} (int)", value.ToString(), v);
string s = value.GetString();
Console.WriteLine("{0} = {1} (string)", value.ToString(), s);
}
Console.ReadLine();
//Results:
//Apples = 1 (int)
//Apples = 1 (string)
//Pears = 2 (int)
//Pears = 2 (string)
}
}
public static class EnumExtensions
{
public static int GetValue(this Enum value)
{
return Convert.ToInt32(value);
}
public static string GetString(this Enum value)
{
return Convert.ToInt32(value).ToString();
}
}
}
I'd like one general purpose function that could be used with any Flags style enum to see if a flag exists.
This doesn't compile, but if anyone has a suggestion, I'd appreciate it.
public static Boolean IsEnumFlagPresent<T>(T value,T lookingForFlag)
where T:enum
{
Boolean result = ((value & lookingForFlag) == lookingForFlag);
return result ;
}
No, you can't do this with C# generics. However, you could do:
public static bool IsEnumFlagPresent<T>(T value, T lookingForFlag)
where T : struct
{
int intValue = (int) (object) value;
int intLookingForFlag = (int) (object) lookingForFlag;
return ((intValue & intLookingForFlag) == intLookingForFlag);
}
This will only work for enums which have an underlying type of int, and it's somewhat inefficient because it boxes the value... but it should work.
You may want to add an execution type check that T is actually an enum type (e.g. typeof(T).BaseType == typeof(Enum))
Here's a complete program demonstrating it working:
using System;
[Flags]
enum Foo
{
A = 1,
B = 2,
C = 4,
D = 8
}
class Test
{
public static Boolean IsEnumFlagPresent<T>(T value, T lookingForFlag)
where T : struct
{
int intValue = (int) (object) value;
int intLookingForFlag = (int) (object) lookingForFlag;
return ((intValue & intLookingForFlag) == intLookingForFlag);
}
static void Main()
{
Console.WriteLine(IsEnumFlagPresent(Foo.B | Foo.C, Foo.A));
Console.WriteLine(IsEnumFlagPresent(Foo.B | Foo.C, Foo.B));
Console.WriteLine(IsEnumFlagPresent(Foo.B | Foo.C, Foo.C));
Console.WriteLine(IsEnumFlagPresent(Foo.B | Foo.C, Foo.D));
}
}
You're looking to replace one line of code with a function that wraps one line of code? I'd say to just use the one line of code...
For what its worth, I recently read that this feature will be part of .NET 4.0. Specifically, it is implemented in the Enum.HasFlag() function.
I have used this before:
public static bool In<T>(this T me, T values)
where T : struct, IConvertible
{
return (me.ToInt64(null) & values.ToInt64(null)) > 0;
}
What I like about it is you can use this clean syntax to call it since in 3.5 the compiler will can infer generic parameters.
AttributeTargets a = AttributeTargets.Class;
if (a.In(AttributeTargets.Class | AttributeTargets.Module))
{
// ...
}
You can do this without generics:
static bool ContainsFlags(Enum value, Enum flag)
{
if (Enum.GetUnderlyingType(value.GetType()) == typeof(ulong))
return (Convert.ToUInt64(value) & Convert.ToUInt64(flag)) == Convert.ToUInt64(flag);
else
return (Convert.ToInt64(value) & Convert.ToInt64(flag)) == Convert.ToInt64(flag);
}
I'm converting to Int64 in this case, which should handle every case except ulong, which is why the extra check...
Why not write an extension method for this? I did this in another post
public static class EnumerationExtensions {
public static bool Has<T>(this System.Enum type, T value) {
try {
return (((int)(object)type & (int)(object)value) == (int)(object)value);
}
catch {
return false;
}
}
//... etc...
}
//Then use it like this
bool hasValue = permissions.Has(PermissionTypes.Delete);
It could use a little refinement (since it assumes everything can be cast as an int), but it could get you started...
Worth pointing out that simply providing some static overloads for all the integral types will work so long as you know you are working with a specific enum. They won't work if the consuming code is likewise operating on where t : struct
If you need to deal with arbitrary (struct) T
You cannot currently do a fast conversion of a generically typed struct into some alternate bitwise form (i.e. roughly speaking a reinterpret_cast) without using C++/CLI
generic <typename T>
where T : value class
public ref struct Reinterpret
{
private:
const static int size = sizeof(T);
public:
static int AsInt(T t)
{
return *((Int32*) (void*) (&t));
}
}
This will then let you write:
static void IsSet<T>(T value, T flags) where T : struct
{
if (!typeof(T).IsEnum)
throw new InvalidOperationException(typeof(T).Name +" is not an enum!");
Type t = Enum.GetUnderlyingType(typeof(T));
if (t == typeof(int))
{
return (Reinterpret.AsInt(value) & Reinterpret.AsInt(flags)) != 0
}
else if (t == typeof(byte))
{
return (Reinterpret.AsByte(value) & Reinterpret.AsByte(flags)) != 0
}
// you get the idea...
}
You cannot constrain to enums. But the mathematical validity of these methods do not change if they are used with non enum types so you could allow them if you can determine that they are convertible to a struct of the relevant size.
Question long over, but here's one for reference anyway:
public static bool HasFlag<TEnum>(this TEnum enumeratedType, TEnum value)
where TEnum : struct, IComparable, IFormattable, IConvertible
{
if (!(enumeratedType is Enum))
{
throw new InvalidOperationException("Struct is not an Enum.");
}
if (typeof(TEnum).GetCustomAttributes(
typeof(FlagsAttribute), false).Length == 0)
{
throw new InvalidOperationException("Enum must use [Flags].");
}
long enumValue = enumeratedType.ToInt64(CultureInfo.InvariantCulture);
long flagValue = value.ToInt64(CultureInfo.InvariantCulture);
if ((enumValue & flagValue) == flagValue)
{
return true;
}
return false;
}
Today, you can set the c# language version to >=7.3
and use the next code as the reference:
public static class EnumExt
{
public static IEnumerable<TEnum> Explode<TEnum>(this TEnum enumValue) where TEnum : Enum
{
var res = Enum.GetValues(enumValue.GetType())
.Cast<TEnum>()
.Where(x => enumValue.HasFlag(x));
return res;
}
public static string ExplodeToString<TEnum>(this TEnum enumValue, string delimeter = ",") where TEnum : Enum
{
return string.Join(delimeter, Explode(enumValue));
}
}
Well, I don't believe there is a way to do this, as there are no constraints that apply to bitwise operators.
However... you can just cast your enum to int and do it.
public static Boolean IsEnumFlagPresent(int value,int lookingForFlag)
{
return ((value & lookingForFlag) == lookingForFlag);
}
This works, but may be confusing to someone.
below is code that benchmarks 4 different methods. results are shown in code in comment "BENCHMARK: .. nSec".
"((enum & flag) != 0)' is 10x faster than HasFlag() function. if you are in a tight loop, then i think it is best to accept it.
public static int jumpCtr=0;
public static int ctr=0;
public static TestFlags gTestFlags = TestFlags.C;
[Flags] public enum TestFlags { A=1<<1, B=1<<2, C=1<<3 }
public static void Jump() { jumpCtr++; gTestFlags = (gTestFlags == TestFlags.B) ? TestFlags.C : TestFlags.B; }
// IsEnumFlagPresent() https://stackoverflow.com/questions/987607/c-flags-enum-generic-function-to-look-for-a-flag
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool HasFlag_Faster<T>(T value, T lookingForFlag)
where T : struct
{
int intValue = (int) (object) value;
int intLookingForFlag = (int) (object) lookingForFlag;
return ((intValue & intLookingForFlag) != 0);
}
// IsEnumFlagPresent() https://stackoverflow.com/questions/987607/c-flags-enum-generic-function-to-look-for-a-flag
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool HasFlag_Faster_Integer(int intValue, int intLookingForFlag)
{
return ((intValue & intLookingForFlag) != 0);
}
public static void Benchmark_HasFlag( )
{
if ( ! hwDvr._weAreOnGswCpu) { return; }
DateTime timer = DateTime.Now;
string a, b, c, d, e;
double base_nSecPerLoop, b_nSecPerLoop, c_nSecPerLoop, d_nSecPerLoop, e_nSecPerLoop;
int numOfLoops = (int) 1.0e6;
// ------------------------------------------------------
for (int i=0; i<numOfLoops;i++) {
Jump();
}
a = BenchMarkSystem_Helper.SimpleTimer_Loops( ref timer, numOfLoops, out base_nSecPerLoop);
// ------------------------------------------------------
// BENCHMARK: 50 nSec
for (int i=0; i<numOfLoops;i++) {
if (gTestFlags.HasFlag((TestFlags) TestFlags.C)) {
ctr++;
}
Jump();
}
b = BenchMarkSystem_Helper.SimpleTimer_Loops( ref timer, numOfLoops, out b_nSecPerLoop );
double b_diff = b_nSecPerLoop - base_nSecPerLoop;
// ------------------------------------------------------
// BENCHMARK: 3 nSec
for (int i=0; i<numOfLoops;i++) {
if ((gTestFlags & TestFlags.C) != 0) {
ctr++;
}
Jump();
}
c = BenchMarkSystem_Helper.SimpleTimer_Loops( ref timer, numOfLoops, out c_nSecPerLoop );
double c_diff = c_nSecPerLoop - base_nSecPerLoop;
// ------------------------------------------------------
// BENCHMARK: 64 nSec
for (int i=0; i<numOfLoops;i++) {
if (HasFlag_Faster<TestFlags>(value:gTestFlags, lookingForFlag: TestFlags.C)) {
ctr++;
}
Jump();
}
d = BenchMarkSystem_Helper.SimpleTimer_Loops( ref timer, numOfLoops, out d_nSecPerLoop );
double d_diff = d_nSecPerLoop - base_nSecPerLoop;
// ------------------------------------------------------
// BENCHMARK: 14 nSec
for (int i=0; i<numOfLoops;i++) {
if (HasFlag_Faster_Integer((int)gTestFlags, (int)TestFlags.C)) {
ctr++;
}
Jump();
}
e = BenchMarkSystem_Helper.SimpleTimer_Loops( ref timer, numOfLoops, out e_nSecPerLoop );
double e_diff = e_nSecPerLoop - base_nSecPerLoop;
int brkPt=0;
}
How do I cast an int to an enum in C#?
From an int:
YourEnum foo = (YourEnum)yourInt;
From a string:
YourEnum foo = (YourEnum) Enum.Parse(typeof(YourEnum), yourString);
// The foo.ToString().Contains(",") check is necessary for
// enumerations marked with a [Flags] attribute.
if (!Enum.IsDefined(typeof(YourEnum), foo) && !foo.ToString().Contains(","))
{
throw new InvalidOperationException(
$"{yourString} is not an underlying value of the YourEnum enumeration."
);
}
From a number:
YourEnum foo = (YourEnum)Enum.ToObject(typeof(YourEnum), yourInt);
Just cast it:
MyEnum e = (MyEnum)3;
Check if it's in range using Enum.IsDefined:
if (Enum.IsDefined(typeof(MyEnum), 3)) { ... }
Alternatively, use an extension method instead of a one-liner:
public static T ToEnum<T>(this string enumString)
{
return (T) Enum.Parse(typeof (T), enumString);
}
Usage:
Color colorEnum = "Red".ToEnum<Color>();
OR
string color = "Red";
var colorEnum = color.ToEnum<Color>();
I think to get a complete answer, people have to know how enums work internally in .NET.
How stuff works
An enum in .NET is a structure that maps a set of values (fields) to a basic type (the default is int). However, you can actually choose the integral type that your enum maps to:
public enum Foo : short
In this case the enum is mapped to the short data type, which means it will be stored in memory as a short and will behave as a short when you cast and use it.
If you look at it from a IL point of view, a (normal, int) enum looks like this:
.class public auto ansi serializable sealed BarFlag extends System.Enum
{
.custom instance void System.FlagsAttribute::.ctor()
.custom instance void ComVisibleAttribute::.ctor(bool) = { bool(true) }
.field public static literal valuetype BarFlag AllFlags = int32(0x3fff)
.field public static literal valuetype BarFlag Foo1 = int32(1)
.field public static literal valuetype BarFlag Foo2 = int32(0x2000)
// and so on for all flags or enum values
.field public specialname rtspecialname int32 value__
}
What should get your attention here is that the value__ is stored separately from the enum values. In the case of the enum Foo above, the type of value__ is int16. This basically means that you can store whatever you want in an enum, as long as the types match.
At this point I'd like to point out that System.Enum is a value type, which basically means that BarFlag will take up 4 bytes in memory and Foo will take up 2 -- e.g. the size of the underlying type (it's actually more complicated than that, but hey...).
The answer
So, if you have an integer that you want to map to an enum, the runtime only has to do 2 things: copy the 4 bytes and name it something else (the name of the enum). Copying is implicit because the data is stored as value type - this basically means that if you use unmanaged code, you can simply interchange enums and integers without copying data.
To make it safe, I think it's a best practice to know that the underlying types are the same or implicitly convertible and to ensure the enum values exist (they aren't checked by default!).
To see how this works, try the following code:
public enum MyEnum : int
{
Foo = 1,
Bar = 2,
Mek = 5
}
static void Main(string[] args)
{
var e1 = (MyEnum)5;
var e2 = (MyEnum)6;
Console.WriteLine("{0} {1}", e1, e2);
Console.ReadLine();
}
Note that casting to e2 also works! From the compiler perspective above this makes sense: the value__ field is simply filled with either 5 or 6 and when Console.WriteLine calls ToString(), the name of e1 is resolved while the name of e2 is not.
If that's not what you intended, use Enum.IsDefined(typeof(MyEnum), 6) to check if the value you are casting maps to a defined enum.
Also note that I'm explicit about the underlying type of the enum, even though the compiler actually checks this. I'm doing this to ensure I don't run into any surprises down the road. To see these surprises in action, you can use the following code (actually I've seen this happen a lot in database code):
public enum MyEnum : short
{
Mek = 5
}
static void Main(string[] args)
{
var e1 = (MyEnum)32769; // will not compile, out of bounds for a short
object o = 5;
var e2 = (MyEnum)o; // will throw at runtime, because o is of type int
Console.WriteLine("{0} {1}", e1, e2);
Console.ReadLine();
}
Take the following example:
int one = 1;
MyEnum e = (MyEnum)one;
I am using this piece of code to cast int to my enum:
if (typeof(YourEnum).IsEnumDefined(valueToCast)) return (YourEnum)valueToCast;
else { //handle it here, if its not defined }
I find it the best solution.
Below is a nice utility class for Enums
public static class EnumHelper
{
public static int[] ToIntArray<T>(T[] value)
{
int[] result = new int[value.Length];
for (int i = 0; i < value.Length; i++)
result[i] = Convert.ToInt32(value[i]);
return result;
}
public static T[] FromIntArray<T>(int[] value)
{
T[] result = new T[value.Length];
for (int i = 0; i < value.Length; i++)
result[i] = (T)Enum.ToObject(typeof(T),value[i]);
return result;
}
internal static T Parse<T>(string value, T defaultValue)
{
if (Enum.IsDefined(typeof(T), value))
return (T) Enum.Parse(typeof (T), value);
int num;
if(int.TryParse(value,out num))
{
if (Enum.IsDefined(typeof(T), num))
return (T)Enum.ToObject(typeof(T), num);
}
return defaultValue;
}
}
For numeric values, this is safer as it will return an object no matter what:
public static class EnumEx
{
static public bool TryConvert<T>(int value, out T result)
{
result = default(T);
bool success = Enum.IsDefined(typeof(T), value);
if (success)
{
result = (T)Enum.ToObject(typeof(T), value);
}
return success;
}
}
If you're ready for the 4.0 .NET Framework, there's a new Enum.TryParse() function that's very useful and plays well with the [Flags] attribute. See Enum.TryParse Method (String, TEnum%)
Sometimes you have an object to the MyEnum type. Like
var MyEnumType = typeof(MyEnum);
Then:
Enum.ToObject(typeof(MyEnum), 3)
If you have an integer that acts as a bitmask and could represent one or more values in a [Flags] enumeration, you can use this code to parse the individual flag values into a list:
for (var flagIterator = 0; flagIterator < 32; flagIterator++)
{
// Determine the bit value (1,2,4,...,Int32.MinValue)
int bitValue = 1 << flagIterator;
// Check to see if the current flag exists in the bit mask
if ((intValue & bitValue) != 0)
{
// If the current flag exists in the enumeration, then we can add that value to the list
// if the enumeration has that flag defined
if (Enum.IsDefined(typeof(MyEnum), bitValue))
Console.WriteLine((MyEnum)bitValue);
}
}
Note that this assumes that the underlying type of the enum is a signed 32-bit integer. If it were a different numerical type, you'd have to change the hardcoded 32 to reflect the bits in that type (or programatically derive it using Enum.GetUnderlyingType())
This is an flags enumeration aware safe convert method:
public static bool TryConvertToEnum<T>(this int instance, out T result)
where T: Enum
{
var enumType = typeof (T);
var success = Enum.IsDefined(enumType, instance);
if (success)
{
result = (T)Enum.ToObject(enumType, instance);
}
else
{
result = default(T);
}
return success;
}
To convert a string to ENUM or int to ENUM constant we need to use Enum.Parse function. Here is a youtube video https://www.youtube.com/watch?v=4nhx4VwdRDk which actually demonstrate's with string and the same applies for int.
The code goes as shown below where "red" is the string and "MyColors" is the color ENUM which has the color constants.
MyColors EnumColors = (MyColors)Enum.Parse(typeof(MyColors), "Red");
Slightly getting away from the original question, but I found an answer to Stack Overflow question Get int value from enum useful. Create a static class with public const int properties, allowing you to easily collect together a bunch of related int constants, and then not have to cast them to int when using them.
public static class Question
{
public static readonly int Role = 2;
public static readonly int ProjectFunding = 3;
public static readonly int TotalEmployee = 4;
public static readonly int NumberOfServers = 5;
public static readonly int TopBusinessConcern = 6;
}
Obviously, some of the enum type functionality will be lost, but for storing a bunch of database id constants, it seems like a pretty tidy solution.
The following is a slightly better extension method:
public static string ToEnumString<TEnum>(this int enumValue)
{
var enumString = enumValue.ToString();
if (Enum.IsDefined(typeof(TEnum), enumValue))
{
enumString = ((TEnum) Enum.ToObject(typeof (TEnum), enumValue)).ToString();
}
return enumString;
}
This parses integers or strings to a target enum with partial matching in .NET 4.0 using generics like in Tawani's utility class. I am using it to convert command-line switch variables which may be incomplete. Since an enum cannot be null, you should logically provide a default value. It can be called like this:
var result = EnumParser<MyEnum>.Parse(valueToParse, MyEnum.FirstValue);
Here's the code:
using System;
public class EnumParser<T> where T : struct
{
public static T Parse(int toParse, T defaultVal)
{
return Parse(toParse + "", defaultVal);
}
public static T Parse(string toParse, T defaultVal)
{
T enumVal = defaultVal;
if (defaultVal is Enum && !String.IsNullOrEmpty(toParse))
{
int index;
if (int.TryParse(toParse, out index))
{
Enum.TryParse(index + "", out enumVal);
}
else
{
if (!Enum.TryParse<T>(toParse + "", true, out enumVal))
{
MatchPartialName(toParse, ref enumVal);
}
}
}
return enumVal;
}
public static void MatchPartialName(string toParse, ref T enumVal)
{
foreach (string member in enumVal.GetType().GetEnumNames())
{
if (member.ToLower().Contains(toParse.ToLower()))
{
if (Enum.TryParse<T>(member + "", out enumVal))
{
break;
}
}
}
}
}
FYI: The question was about integers, which nobody mentioned will also explicitly convert in Enum.TryParse()
From a string: (Enum.Parse is out of Date, use Enum.TryParse)
enum Importance
{}
Importance importance;
if (Enum.TryParse(value, out importance))
{
}
You should build in some type matching relaxation to be more robust.
public static T ToEnum<T>(dynamic value)
{
if (value == null)
{
// default value of an enum is the object that corresponds to
// the default value of its underlying type
// https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/default-values-table
value = Activator.CreateInstance(Enum.GetUnderlyingType(typeof(T)));
}
else if (value is string name)
{
return (T)Enum.Parse(typeof(T), name);
}
return (T)Enum.ToObject(typeof(T),
Convert.ChangeType(value, Enum.GetUnderlyingType(typeof(T))));
}
Test Case
[Flags]
public enum A : uint
{
None = 0,
X = 1 < 0,
Y = 1 < 1
}
static void Main(string[] args)
{
var value = EnumHelper.ToEnum<A>(7m);
var x = value.HasFlag(A.X); // true
var y = value.HasFlag(A.Y); // true
var value2 = EnumHelper.ToEnum<A>("X");
var value3 = EnumHelper.ToEnum<A>(null);
Console.ReadKey();
}
Here's an extension method that casts Int32 to Enum.
It honors bitwise flags even when the value is higher than the maximum possible. For example if you have an enum with possibilities 1, 2, and 4, but the int is 9, it understands that as 1 in absence of an 8. This lets you make data updates ahead of code updates.
public static TEnum ToEnum<TEnum>(this int val) where TEnum : struct, IComparable, IFormattable, IConvertible
{
if (!typeof(TEnum).IsEnum)
{
return default(TEnum);
}
if (Enum.IsDefined(typeof(TEnum), val))
{//if a straightforward single value, return that
return (TEnum)Enum.ToObject(typeof(TEnum), val);
}
var candidates = Enum
.GetValues(typeof(TEnum))
.Cast<int>()
.ToList();
var isBitwise = candidates
.Select((n, i) => {
if (i < 2) return n == 0 || n == 1;
return n / 2 == candidates[i - 1];
})
.All(y => y);
var maxPossible = candidates.Sum();
if (
Enum.TryParse(val.ToString(), out TEnum asEnum)
&& (val <= maxPossible || !isBitwise)
){//if it can be parsed as a bitwise enum with multiple flags,
//or is not bitwise, return the result of TryParse
return asEnum;
}
//If the value is higher than all possible combinations,
//remove the high imaginary values not accounted for in the enum
var excess = Enumerable
.Range(0, 32)
.Select(n => (int)Math.Pow(2, n))
.Where(n => n <= val && n > 0 && !candidates.Contains(n))
.Sum();
return Enum.TryParse((val - excess).ToString(), out asEnum) ? asEnum : default(TEnum);
}
The easy and clear way for casting an int to enum in C#:
public class Program
{
public enum Color : int
{
Blue = 0,
Black = 1,
Green = 2,
Gray = 3,
Yellow = 4
}
public static void Main(string[] args)
{
// From string
Console.WriteLine((Color) Enum.Parse(typeof(Color), "Green"));
// From int
Console.WriteLine((Color)2);
// From number you can also
Console.WriteLine((Color)Enum.ToObject(typeof(Color), 2));
}
}
For string, you can do the following:
var result = Enum.TryParse(typeof(MyEnum), yourString, out yourEnum)
And make sure to check the result to determine if the conversion failed.
For int, you can do the following:
MyEnum someValue = (MyEnum)myIntValue;
In my case, I needed to return the enum from a WCF service. I also needed a friendly name, not just the enum.ToString().
Here's my WCF Class.
[DataContract]
public class EnumMember
{
[DataMember]
public string Description { get; set; }
[DataMember]
public int Value { get; set; }
public static List<EnumMember> ConvertToList<T>()
{
Type type = typeof(T);
if (!type.IsEnum)
{
throw new ArgumentException("T must be of type enumeration.");
}
var members = new List<EnumMember>();
foreach (string item in System.Enum.GetNames(type))
{
var enumType = System.Enum.Parse(type, item);
members.Add(
new EnumMember() { Description = enumType.GetDescriptionValue(), Value = ((IConvertible)enumType).ToInt32(null) });
}
return members;
}
}
Here's the Extension method that gets the Description from the Enum.
public static string GetDescriptionValue<T>(this T source)
{
FieldInfo fileInfo = source.GetType().GetField(source.ToString());
DescriptionAttribute[] attributes = (DescriptionAttribute[])fileInfo.GetCustomAttributes(typeof(DescriptionAttribute), false);
if (attributes != null && attributes.Length > 0)
{
return attributes[0].Description;
}
else
{
return source.ToString();
}
}
Implementation:
return EnumMember.ConvertToList<YourType>();
It can help you to convert any input data to user desired enum. Suppose you have an enum like below which by default int. Please add a Default value at first of your enum. Which is used at helpers medthod when there is no match found with input value.
public enum FriendType
{
Default,
Audio,
Video,
Image
}
public static class EnumHelper<T>
{
public static T ConvertToEnum(dynamic value)
{
var result = default(T);
var tempType = 0;
//see Note below
if (value != null &&
int.TryParse(value.ToString(), out tempType) &&
Enum.IsDefined(typeof(T), tempType))
{
result = (T)Enum.ToObject(typeof(T), tempType);
}
return result;
}
}
N.B: Here I try to parse value into int, because enum is by default int
If you define enum like this which is byte type.
public enum MediaType : byte
{
Default,
Audio,
Video,
Image
}
You need to change parsing at helper method from
int.TryParse(value.ToString(), out tempType)
to
byte.TryParse(value.ToString(), out tempType)
I check my method for following inputs
EnumHelper<FriendType>.ConvertToEnum(null);
EnumHelper<FriendType>.ConvertToEnum("");
EnumHelper<FriendType>.ConvertToEnum("-1");
EnumHelper<FriendType>.ConvertToEnum("6");
EnumHelper<FriendType>.ConvertToEnum("");
EnumHelper<FriendType>.ConvertToEnum("2");
EnumHelper<FriendType>.ConvertToEnum(-1);
EnumHelper<FriendType>.ConvertToEnum(0);
EnumHelper<FriendType>.ConvertToEnum(1);
EnumHelper<FriendType>.ConvertToEnum(9);
sorry for my english
Different ways to cast to and from Enum
enum orientation : byte
{
north = 1,
south = 2,
east = 3,
west = 4
}
class Program
{
static void Main(string[] args)
{
orientation myDirection = orientation.north;
Console.WriteLine(“myDirection = {0}”, myDirection); //output myDirection =north
Console.WriteLine((byte)myDirection); //output 1
string strDir = Convert.ToString(myDirection);
Console.WriteLine(strDir); //output north
string myString = “north”; //to convert string to Enum
myDirection = (orientation)Enum.Parse(typeof(orientation),myString);
}
}
I don't know anymore where I get the part of this enum extension, but it is from stackoverflow. I am sorry for this! But I took this one and modified it for enums with Flags.
For enums with Flags I did this:
public static class Enum<T> where T : struct
{
private static readonly IEnumerable<T> All = Enum.GetValues(typeof (T)).Cast<T>();
private static readonly Dictionary<int, T> Values = All.ToDictionary(k => Convert.ToInt32(k));
public static T? CastOrNull(int value)
{
T foundValue;
if (Values.TryGetValue(value, out foundValue))
{
return foundValue;
}
// For enums with Flags-Attribut.
try
{
bool isFlag = typeof(T).GetCustomAttributes(typeof(FlagsAttribute), false).Length > 0;
if (isFlag)
{
int existingIntValue = 0;
foreach (T t in Enum.GetValues(typeof(T)))
{
if ((value & Convert.ToInt32(t)) > 0)
{
existingIntValue |= Convert.ToInt32(t);
}
}
if (existingIntValue == 0)
{
return null;
}
return (T)(Enum.Parse(typeof(T), existingIntValue.ToString(), true));
}
}
catch (Exception)
{
return null;
}
return null;
}
}
Example:
[Flags]
public enum PetType
{
None = 0, Dog = 1, Cat = 2, Fish = 4, Bird = 8, Reptile = 16, Other = 32
};
integer values
1=Dog;
13= Dog | Fish | Bird;
96= Other;
128= Null;
You simply use Explicit conversion Cast int to enum or enum to int
class Program
{
static void Main(string[] args)
{
Console.WriteLine((int)Number.three); //Output=3
Console.WriteLine((Number)3);// Outout three
Console.Read();
}
public enum Number
{
Zero = 0,
One = 1,
Two = 2,
three = 3
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
namespace SamplePrograme
{
public class Program
{
public enum Suit : int
{
Spades = 0,
Hearts = 1,
Clubs = 2,
Diamonds = 3
}
public static void Main(string[] args)
{
//from string
Console.WriteLine((Suit) Enum.Parse(typeof(Suit), "Clubs"));
//from int
Console.WriteLine((Suit)1);
//From number you can also
Console.WriteLine((Suit)Enum.ToObject(typeof(Suit) ,1));
}
}
}
I prefer a short way using a nullable enum type variable.
var enumValue = (MyEnum?)enumInt;
if (!enumValue.HasValue)
{
throw new ArgumentException(nameof(enumValue));
}
You just do like below:
int intToCast = 1;
TargetEnum f = (TargetEnum) intToCast ;
To make sure that you only cast the right values and that you can throw an exception otherwise:
int intToCast = 1;
if (Enum.IsDefined(typeof(TargetEnum), intToCast ))
{
TargetEnum target = (TargetEnum)intToCast ;
}
else
{
// Throw your exception.
}
Note that using IsDefined is costly and even more than just casting, so it depends on your implementation to decide to use it or not.
You can use an extension method.
public static class Extensions
{
public static T ToEnum<T>(this string data) where T : struct
{
if (!Enum.TryParse(data, true, out T enumVariable))
{
if (Enum.IsDefined(typeof(T), enumVariable))
{
return enumVariable;
}
}
return default;
}
public static T ToEnum<T>(this int data) where T : struct
{
return (T)Enum.ToObject(typeof(T), data);
}
}
Use it like the below code:
Enum:
public enum DaysOfWeeks
{
Monday = 1,
Tuesday = 2,
Wednesday = 3,
Thursday = 4,
Friday = 5,
Saturday = 6,
Sunday = 7,
}
Usage:
string Monday = "Mon";
int Wednesday = 3;
var Mon = Monday.ToEnum<DaysOfWeeks>();
var Wed = Wednesday.ToEnum<DaysOfWeeks>();