String Enum

Scott Baldridge
Scott Baldridge used Ask the Experts™
on
Hello, I have an enum like so:

 public enum PermissionType
    {
  [EnumValueName("Paid Customer")]
        PaidCustomer
    }


If I have "Paid Customer" how do I get PaidCustomer?
Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
Éric MoreauSenior .Net Consultant
Top Expert 2016

Commented:
Does ToString() not work?
Top Expert 2015

Commented:
What is EnumValueName? This is not something that is documented, so I do not know how to use it to get the reference.

But assuming a variable named permission that has the proper value:

permission.ToString()
Exploring SQL Server 2016: Fundamentals

Learn the fundamentals of Microsoft SQL Server, a relational database management system that stores and retrieves data when requested by other software applications.

Commented:
Using reflection:
using System;

namespace EE_Q28869700
{
	class Program
	{
		static void Main(string[] args)
		{
			var value = "Paid Customer".GetValueFromEnumValueName<PermissionType>();
			Console.WriteLine(value);
			Console.ReadLine();
		}
	}

	enum PermissionType
	{
		[EnumValueName("Paid Customer")]
		PaidCustomer
	}

	class EnumValueNameAttribute : Attribute
	{
		public string Name { get; set; }

		public EnumValueNameAttribute() { ;}
		public EnumValueNameAttribute(string name)
		{
			Name = name;
		}
	}

	static class Extensions
	{
		public static T GetValueFromEnumValueName<T>(this string name)
		{
			var type = typeof(T);
			if (!type.IsEnum) 
				throw new InvalidOperationException();

			foreach (var field in type.GetFields())
			{
				var attribute = Attribute.GetCustomAttribute(field, typeof(EnumValueNameAttribute)) as EnumValueNameAttribute;
				if (attribute != null)
				{
					if (attribute.Name == name)
						return (T)field.GetValue(null);
				}
				else
				{
					if (field.Name == name)
						return (T)field.GetValue(null);
				}
			}
			throw new ArgumentException("Not found.", "name");
		}
	}
}

Open in new window

Which produces the following output -Capture.JPG-saige-

Commented:
A more *non-intuitive* selection:
using System;
using System.ComponentModel;

namespace EE_Q28869700
{
	class Program
	{
		static void Main(string[] args)
		{
			var value = "Paid Customer".GetValueFromEnumValueName<PermissionType>();
			Console.WriteLine(value);
			value = "Egads".GetValueFromEnumValueName<PermissionType>();
			Console.WriteLine(value);
			Console.ReadLine();
		}
	}

	enum PermissionType
	{
		[EnumValueName("Paid Customer")]
		PaidCustomer,
		[EnumValueName("Egads")]
		UnpaidCustomer
	}

	class EnumValueNameAttribute : Attribute
	{
		public string Name { get; set; }

		public EnumValueNameAttribute() { ;}
		public EnumValueNameAttribute(string name)
		{
			Name = name;
		}
	}

	static class Extensions
	{
		public static T GetValueFromEnumValueName<T>(this string name)
		{
			var type = typeof(T);
			if (!type.IsEnum) 
				throw new InvalidOperationException();

			foreach (var field in type.GetFields())
			{
				var attribute = Attribute.GetCustomAttribute(field, typeof(EnumValueNameAttribute)) as EnumValueNameAttribute;
				if (attribute != null)
				{
					if (attribute.Name == name)
						return (T)field.GetValue(null);
				}
				else
				{
					if (field.Name == name)
						return (T)field.GetValue(null);
				}
			}
			throw new ArgumentException("Not found.", "name");
		}
	}
}

Open in new window

Which now produces the following output -Capture.JPG-saige-

Author

Commented:
I tried to get PaidCustomer like this :

string permissionName = Roles.GetPermissionName(permissionId);
//permissionName = "Paid Customer"

 PermissionType permission =  (PermissionType) Enum.Parse(typeof(PermissionType), permissionName);

but get this error: Requested value 'Paid Customer' was not found.

Commented:
Correct, Parse will only work if the string matches the enum value.  This is where the extension method plays it's role in order to match the string value with the EnumValueName attribute.

-saige-
Commented:
In other words:
using System;
using System.ComponentModel;

namespace EE_Q28869700
{
	class Program
	{
		static void Main(string[] args)
		{
			string val1 = "Paid Customer";
			string val2 = "Egads";
			var value = val1.GetValueFromEnumValueName<PermissionType>();
			Console.WriteLine(value);
			value = val2.GetValueFromEnumValueName<PermissionType>();
			Console.WriteLine(value);
			Console.ReadLine();
		}
	}

	enum PermissionType
	{
		[EnumValueName("Paid Customer")]
		PaidCustomer,
		[EnumValueName("Egads")]
		UnpaidCustomer
	}

	class EnumValueNameAttribute : Attribute
	{
		public string Name { get; set; }

		public EnumValueNameAttribute() { ;}
		public EnumValueNameAttribute(string name)
		{
			Name = name;
		}
	}

	static class Extensions
	{
		public static T GetValueFromEnumValueName<T>(this string name)
		{
			var type = typeof(T);
			if (!type.IsEnum) 
				throw new InvalidOperationException();

			foreach (var field in type.GetFields())
			{
				var attribute = Attribute.GetCustomAttribute(field, typeof(EnumValueNameAttribute)) as EnumValueNameAttribute;
				if (attribute != null)
				{
					if (attribute.Name == name)
						return (T)field.GetValue(null);
				}
				else
				{
					if (field.Name == name)
						return (T)field.GetValue(null);
				}
			}
			throw new ArgumentException("Not found.", "name");
		}
	}
}

Open in new window

Works just as well.  It should be noted, however, that these are currently case-sensitive searches.  If you want them to not be case-sensitive, then we would need to use IndexOf with a comparer; e.g. -
using System;
using System.ComponentModel;

namespace EE_Q28869700
{
	class Program
	{
		static void Main(string[] args)
		{
			string val1 = "paid customer";
			string val2 = "egaDS";
			var value = val1.GetValueFromEnumValueName<PermissionType>();
			Console.WriteLine(value);
			value = val2.GetValueFromEnumValueName<PermissionType>();
			Console.WriteLine(value);
			Console.ReadLine();
		}
	}

	enum PermissionType
	{
		[EnumValueName("Paid Customer")]
		PaidCustomer,
		[EnumValueName("Egads")]
		UnpaidCustomer
	}

	class EnumValueNameAttribute : Attribute
	{
		public string Name { get; set; }

		public EnumValueNameAttribute() { ;}
		public EnumValueNameAttribute(string name)
		{
			Name = name;
		}
	}

	static class Extensions
	{
		public static T GetValueFromEnumValueName<T>(this string name)
		{
			var type = typeof(T);
			if (!type.IsEnum) 
				throw new InvalidOperationException();

			foreach (var field in type.GetFields())
			{
				var attribute = Attribute.GetCustomAttribute(field, typeof(EnumValueNameAttribute)) as EnumValueNameAttribute;
				if (attribute != null)
				{
					if (attribute.Name.IndexOf(name, StringComparison.OrdinalIgnoreCase) == 0)
						return (T)field.GetValue(null);
				}
				else
				{
					if (field.Name.IndexOf(name, StringComparison.OrdinalIgnoreCase) == 0)
						return (T)field.GetValue(null);
				}
			}
			throw new ArgumentException("Not found.", "name");
		}
	}
}

Open in new window

Which would produce the same output as above (using a case-insensitive search).

-saige-

Author

Commented:
Thank you! I'm going to give it a go!
Top Expert 2015

Commented:
@it_saige

Where did you get the documentation for the EnumValueName attribute? I cannot find it anywhere, even by googling it.

Author

Commented:
WOW! that is the way to go! Works perfectly!

Commented:
I just assumed it was a custom attribute since it was enclosed in Attribute declarative markup.  From there, the attributes constructor accepts a string so I just assumed that the string's property was Name since the attributes name was EnumValueName.

-saige-

Commented:
Glad that worked out for you Earnie.

-saige-
@Jacques Bourgeois... I believe that it is a custom attribute. I think i remember a project online somewhere..... if i find it i will post.

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial