I have an enum
enum myEnum2 { ab, st, top, under, below}
I would like to write a function to test if a given value is included in myEnum
something like that:
private bool EnumContainValue(Enum myEnum, string myValue)
{
return Enum.GetValues(typeof(myEnum))
.ToString().ToUpper().Contains(myValue.ToUpper());
}
But it doesn't work because myEnum parameter is not recognized.
Why not use
Enum.IsDefined(typeof(myEnum), value);
BTW it's nice to create generic Enum<T> class, which wraps around calls to Enum (actually I wonder why something like this was not added to Framework 2.0 or later):
public static class Enum<T>
{
public static bool IsDefined(string name)
{
return Enum.IsDefined(typeof(T), name);
}
public static bool IsDefined(T value)
{
return Enum.IsDefined(typeof(T), value);
}
public static IEnumerable<T> GetValues()
{
return Enum.GetValues(typeof(T)).Cast<T>();
}
// etc
}
This allows to avoid all this typeof stuff and use strongly-typed values:
Enum<StringSplitOptions>.IsDefined("None")
No need to write your own:
// Summary:
// Returns an indication whether a constant with a specified value exists in
// a specified enumeration.
//
// Parameters:
// enumType:
// An enumeration type.
//
// value:
// The value or name of a constant in enumType.
//
// Returns:
// true if a constant in enumType has a value equal to value; otherwise, false.
public static bool IsDefined(Type enumType, object value);
Example:
if (System.Enum.IsDefined(MyEnumType, MyValue))
{
// Do something
}
just use this method
Enum.IsDefined Method - Returns an indication whether a constant with a specified value exists in a specified enumeration
Example
enum myEnum2 { ab, st, top, under, below};
myEnum2 value = myEnum2.ab;
Console.WriteLine("{0:D} Exists: {1}",
value, myEnum2.IsDefined(typeof(myEnum2), value));
What you're doing with ToString() in this case is to:
Enum.GetValues(typeof(myEnum)).ToString()... instead you should write:
Enum.GetValues(typeof(myEnum).ToString()...
The difference is in the parentheses...
Also can use this:
enum myEnum2 { ab, st, top, under, below }
static void Main(string[] args)
{
myEnum2 r;
string name = "ab";
bool result = Enum.TryParse(name, out r);
}
The result will contain whether the value is contained in enum or not.
public static T ConvertToEnum<T>(this string value)
{
if (typeof(T).BaseType != typeof(Enum))
{
throw new InvalidCastException("The specified object is not an enum.");
}
if (Enum.IsDefined(typeof(T), value.ToUpper()) == false)
{
throw new InvalidCastException("The parameter value doesn't exist in the specified enum.");
}
return (T)Enum.Parse(typeof(T), value.ToUpper());
}
If your question is like "I have an enum type, enum MyEnum { OneEnumMember, OtherEnumMember }, and I'd like to have a function which tells whether this enum type contains a member with a specific name, then what you're looking for is the System.Enum.IsDefined method:
Enum.IsDefined(typeof(MyEnum), MyEnum.OneEnumMember); //returns true
Enum.IsDefined(typeof(MyEnum), "OtherEnumMember"); //returns true
Enum.IsDefined(typeof(MyEnum), "SomethingDifferent"); //returns false
If your question is like "I have an instance of an enum type, which has Flags attribute, and I'd like to have a function which tells whether this instance contains a specific enum value, then the function looks something like this:
public static bool ContainsValue<TEnum>(this TEnum e, TEnum val) where Enum: struct, IComparable, IFormattable, IConvertible
{
if (!e.GetType().IsEnum)
throw new ArgumentException("The type TEnum must be an enum type.", nameof(TEnum));
dynamic val1 = e, val2 = val;
return (val1 | val2) == val1;
}
Hope I could help.
Use the correct name of the enum (myEnum2).
Also, if you're testing against a string value you may want to use GetNames instead of GetValues.
just cast the enum as:
string something = (string)myEnum;
and now comparison is easy as you like
I think that you go wrong when using ToString().
Try making a Linq query
private bool EnumContainValue(Enum myEnum, string myValue)
{
var query = from enumVal in Enum.GetNames(typeof(GM)).ToList()
where enumVal == myValue
select enumVal;
return query.Count() == 1;
}
Related
I have an enum type like this as an example:
public Enum MyEnum {
enum1, enum2, enum3 };
I'll read a string from config file. What I need is to parse the string to MyEnum type or null or not defined. Not sure if the following code will work (sorry for not having access to my VS right now):
// example: ParseEnum<MyEnum>("ENUM1", ref eVal);
bool ParseEnum<T>(string value1, ref eVal) where T : Enum
{
bool bRet = false;
var x = from x in Enum.GetNames(typeof(T)) where
string.Equals(value1, x, StringComparison. OrdinalIgnoreCase)
select x;
if (x.Count() == 1 )
{
eVal = Enum.Parse(typeof(T), x.Item(0)) as T;
bRet = true;
}
return bRet;
}
Not sure if it is correct or there is any other simple way to parse a string to a MyEnum value?
What about something like:
public static class EnumUtils
{
public static Nullable<T> Parse<T>(string input) where T : struct
{
//since we cant do a generic type constraint
if (!typeof(T).IsEnum)
{
throw new ArgumentException("Generic Type 'T' must be an Enum");
}
if (!string.IsNullOrEmpty(input))
{
if (Enum.GetNames(typeof(T)).Any(
e => e.Trim().ToUpperInvariant() == input.Trim().ToUpperInvariant()))
{
return (T)Enum.Parse(typeof(T), input, true);
}
}
return null;
}
}
Used as:
MyEnum? value = EnumUtils.Parse<MyEnum>("foo");
(Note: old version used try/catch around Enum.Parse)
private enum MyEnum
{
Enum1 = 1, Enum2 = 2, Enum3 = 3, Enum4 = 4, Enum5 = 5, Enum6 = 6,
Enum7 = 7, Enum8 = 8, Enum9 = 9, Enum10 = 10
}
private static Object ParseEnum<T>(string s)
{
try
{
var o = Enum.Parse(typeof (T), s);
return (T)o;
}
catch(ArgumentException)
{
return null;
}
}
static void Main(string[] args)
{
Console.WriteLine(ParseEnum<MyEnum>("Enum11"));
Console.WriteLine(ParseEnum<MyEnum>("Enum1"));
Console.WriteLine(ParseEnum<MyEnum>("Enum6").GetType());
Console.WriteLine(ParseEnum<MyEnum>("Enum10"));
}
OUTPUT:
//This line is empty as Enum11 is not there and function returns a null
Enum1
TestApp.Program+MyEnum
Enum10
Press any key to continue . . .
This is an old question, but now .NET 4.5 has Enum.TryParse<TEnum>().
I have a TryParseName method in UnconstrainedMelody, a library for delegate and enum utility methods which uses "inexpressible" constraints via some postbuild trickery. (Code using the library doesn't need a postbuild, just to be clear.)
You would use it like this:
Foo foo;
bool parsed = Enums.TryParseName<Foo>(name, out foo);
I don't currently have a case-insensitive version, but I could easily introduce one if you wanted. Note that this doesn't try to parse numbers e.g. "12" like the built-in version does, nor does it try to parse comma-separated lists of flags. I may add the flags version later on, but I can't see much point in the numeric version.
This is done without boxing and without execution time type checking. Having the constraint is really handy :)
Please let me know if you'd find a case-insensitive parse useful...
If you're using .NET 3.5 (or even 2.0, if you trim out the extension method), I've had great luck with the techniques in this article:
Enumerations and Strings - Stop the Madness!
EDIT: Domain is gone and is now a link farm. I pulled the code (slightly modified and added to over time) from our codebase at work, which you can now find here:
https://gist.github.com/1305566
You can use TryParse if you want to avoid using try/catch.
MyEnum eVal;
if (Enum.TryParse("ENUM2", true, out eVal)){
// now eVal is the enumeration element: enum2
}
//unable to parse. You can log the error, exit, redirect, etc...
I modified the selected answer a little bit. I hope you like it.
public static class EnumUtils
{
public static Nullable<T> Parse<T>(string input) where T : struct
{
//since we cant do a generic type constraint
if (!typeof(T).IsEnum)
{
throw new ArgumentException("Generic Type 'T' must be an Enum");
}
int intVal;
if (!string.IsNullOrEmpty(input) && !int.TryParse(input, out intVal))
{
T eVal;
if (Enum.TryParse(input, true, out eVal))
{
return eVal;
}
}
return null;
}
}
I have just combined the syntax from here, with the exception handling from here, to create this:
public static class Enum<T>
{
public static T Parse(string value)
{
//Null check
if(value == null) throw new ArgumentNullException("value");
//Empty string check
value = value.Trim();
if(value.Length == 0) throw new ArgumentException("Must specify valid information for parsing in the string", "value");
//Not enum check
Type t = typeof(T);
if(!t.IsEnum) throw new ArgumentException("Type provided must be an Enum", "TEnum");
return (T)Enum.Parse(typeof(T), value);
}
}
You could twiddle it a bit to return null instead of throwing exceptions.
To return Enum by string, if contains:
public static T GetEnum<T>(string s)
{
Array arr = Enum.GetValues(typeof(T));
foreach (var x in arr)
{
if (x.ToString().Contains(s))
return (T)x;
}
return default(T);
}
sorry for asking this question but i didn't found the right solution for this task:
I've got a Enum, which is named "myEnum" (MyEnum isn't known by the function)
I Need to get the int value of a Value of myEnum
Example:
A Programmer named its enum "myEnum":
public enum myEnum
{
foo = 1,
bar = 2,
}
my function should do the following:
Get the Value of "foo" of "myEnum" by string
function should opened by:
public int GetValueOf(string EnumName, string EnumConst)
{
}
so when Programmer A opens it by :
int a = GetValueOf("myEnum","foo");
it should return 1
and when Programmer B has an Enum named "mySpace", wants to return "bar" with Value 5
int a = GetValueOf("mySpace","bar")
should return 5
how can i do this?
You can use Enum.Parse to do this, but you'd need the fully qualified type name of the Enum type, ie: "SomeNamespace.myEnum":
public static int GetValueOf(string enumName, string enumConst)
{
Type enumType = Type.GetType(enumName);
if (enumType == null)
{
throw new ArgumentException("Specified enum type could not be found", "enumName");
}
object value = Enum.Parse(enumType, enumConst);
return Convert.ToInt32(value);
}
Also note that this uses Convert.ToInt32 instead of a cast. This will handle enum values with underlying types which are not Int32. This will still throw an OverflowException, however, if your enum has an underlying value outside of the range of an Int32 (ie: if it's a ulong as the value is >int.MaxValue).
Please try
int result = (int) Enum.Parse(Type.GetType(EnumName), EnumConst);
I suppose you're trying to instance the enum from the string value (it's name) then I'll suggest you to get it members via reflection and then compare.
Please be aware reflection adds a bit of overhead.
It's not clear to me if the name of the enum type must be specified as a string.
You need to use Enum.TryParse to get the value of the Enum. In combination with a generic method, you could do something like this:
public int? GetValueOf<T>(string EnumConst) where T : struct
{
int? result = null;
T temp = default(T);
if (Enum.TryParse<T>(EnumConst, out temp))
{
result = Convert.ToInt32(temp);
}
return result;
}
To call it use this:
int? result = GetValueOf<myEnum>("bar");
if (result.HasValue)
{
//work with value here.
}
I have the following enumeration:
public enum MyEnum
{
MyTrue,
MyFalse
}
And I'd like to eventually be able to automatically convert my enumeration to a boolean value, with a simple line like this:
MyEnum val = MyEnum.MyTrue;
bool IsThisTrue = val;
Currently, I have to do this:
bool IsThisTrue = val == MyEnum.MyTrue;
Is there some mechanism I can apply to my enumeration to allow for native enum->bool casting? I'm wondering if some variant of a typeconverter is what I need or not.
Thanks
Edit: There is a reason for my custom enumeration. Since this properties are all eventually bound to a property grid, we have mechanisms put in place to bind all of our custom enumerations to multi-lingual strings in resources files. We need all of the enum's we're using to be in a specific namespace, hence the "MyEnum" class.
That line would work only with an implicit static conversion operator (or maybe the more-confusing true() operator, but that is rarely seen in the wild). You cannot define operators on enums, so ultimately the answer is: no.
You could, however, write an extension method on MyEnum to return true or false.
static class MyEnumUtils {
public static bool Value(this MyEnum value) {
switch(value) {
case MyEnum.MyTrue: return true;
case MyEnum.MyFalse: return false;
default: throw new ArgumentOutOfRangeException("value");
// ^^^ yes, that is possible
}
}
}
then you can use bool IsThisTrue = val.Value();
Write an extension method like this:
public static bool ToBoolean(this MyEnum value) {
return value == MyEnum.MyTrue;
}
and forget about it
Try this:
public enum MyEnum
{
MyFalse = 0,
MyTrue = 1
}
then:
MyEnum val = MyEnum.MyTrue;
bool IsThisTrue = val;
bool IsThisTrue = Convert.ToBoolean((int)val);
Given an enum type:
enum SOMEENUM
{
A = true,
B = false,
C = true
}
I want to switch on this like:
public void SWITCHON (SOMEENUM sn)
{
switch(s)
{
case SOMEENMUM.A : xxxxxxxx.......
}
}
But this doesn't compile; I guess it's using the bool value of the enum.
I want to do switch on Enum as if there is no value assigned to it.
First of all:
Enums in C# do not support bool as value.
So It should be integers.
If we set 2 property's of enum to the same value we can consider one of them lost.
From my understanding what you actually is trying to do is:
Somehow flag that 2 property's of enum are equal.
My suggestion:
public enum MyEnum
{
[Description("true")]
A = 1,
[Description("false")]
B = 2,
[Description("true")]
C = 3
}
Extension for Enum which will return bool
public static class EnumEx
{
public static bool GetDescriptionAsBool(this Enum value)
{
FieldInfo field = value.GetType().GetField(value.ToString());
DescriptionAttribute attribute
= Attribute.GetCustomAttribute(field, typeof(DescriptionAttribute))
as DescriptionAttribute;
if(attribute == null)
{
//throw new SomethingWentWrongException();
}
return bool.Parse(attribute.Description);
}
}
As a result you can switch normally and at any time can check what is your enums boll flag just calling GetDescriptionAsBool method of that instance.
Repeated values are just different names for the same thing. There's no way to tell the difference because enums are stored as the values, not as the names.
As for bool values, you use an if for those instead of a switch.
enums require numerical values but do not have to be set. I suggest just removing leaving it like
enum SOMEENUM
{
A,
B,
C
}
so
public void SWITCHON (SOMEENUM s)
{
switch(s)
{
case SOMEENMUM.A : ...do stuff...
break;
case SOMEENMUM.B : ...do stuff...
break;
case SOMEENMUM.c : ...do stuff...
break;
}
}
I'm sure this is fairly trivial but I can't get it right.
public static string DoSomething(this Enum value)
{
if (!Enum.IsDefined(value.GetType(), value))
{
// not a valid value, assume default value
value = default(value.GetType());
}
// ... do some other stuff
}
The line value = default(value.GetType()); doesn't compile, but hopefully you can see what I'm attempting. I need to set the Enum param to the default value of it's own type.
I'm not really sure what you're trying to do here, but a version of the 'default' line which does compile is this:
value = (Enum)Enum.GetValues(value.GetType()).GetValue(0);
Or, even cleaner (from Paw, in the comments, thanks):
value = (Enum) Enum.ToObject(value.GetType(), 0);
This second version does only work properly if you know the enum's first element has a value of zero.
You actually could do what Paw is suggesting, even with a generic constraint, if you could move this method to its own class:
public abstract class Helper<T>
{
public static string DoSomething<TEnum>(TEnum value) where TEnum: struct, T
{
if (!Enum.IsDefined(typeof(TEnum), value))
{
value = default(TEnum);
}
// ... do some other stuff
// just to get code to compile
return value.ToString();
}
}
public class EnumHelper : Helper<Enum> { }
Then you would do, for example:
MyEnum x = MyEnum.SomeValue;
MyEnum y = (MyEnum)100; // Let's say this is undefined.
EnumHelper.DoSomething(x); // generic type of MyEnum can be inferred
EnumHelper.DoSomething(y); // same here
As Konrad Rudolph points out in a comment, default(TEnum) in the above code will evaluate to 0, regardless of whether or not a value is defined for 0 for the given TEnum type. If that's not what you want, Will's answer provides certainly the easiest way of getting the first defined value ((TEnum)Enum.GetValues(typeof(TEnum)).GetValue(0)).
On the other hand, if you want to take this to the extreme, and cache the result so that you don't always have to box it, you could do that:
public abstract class Helper<T>
{
static Dictionary<Type, T> s_defaults = new Dictionary<Type, T>();
public static string DoSomething<TEnum>(TEnum value) where TEnum: struct, T
{
if (!Enum.IsDefined(typeof(TEnum), value))
{
value = GetDefault<TEnum>();
}
// ... do some other stuff
// just to get code to compile
return value.ToString();
}
public static TEnum GetDefault<TEnum>() where TEnum : struct, T
{
T definedDefault;
if (!s_defaults.TryGetValue(typeof(TEnum), out definedDefault))
{
// This is the only time you'll have to box the defined default.
definedDefault = (T)Enum.GetValues(typeof(TEnum)).GetValue(0);
s_defaults[typeof(TEnum)] = definedDefault;
}
// Every subsequent call to GetDefault on the same TEnum type
// will unbox the same object.
return (TEnum)definedDefault;
}
}
Activator.CreateInstance(typeof(ConsoleColor)) seems to work
Enum by default have its first value as default value
Have you thought about making it a generic method?
public static string DoSomething<T>(Enum value)
{
if (!Enum.IsDefined(typeof(T), value))
{
value = (T)Enum.ToObject(typeof(T), 0);
}
// ... do some other stuff
}
The caller of the method should know the type.