String Enum

Hello, I have an enum like so:

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


If I have "Paid Customer" how do I get PaidCustomer?
Scott BaldridgeAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Éric MoreauSenior .Net ConsultantCommented:
p_davisCommented:
Does ToString() not work?
Jacques Bourgeois (James Burger)PresidentCommented:
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()
Microsoft Azure 2017

Azure has a changed a lot since it was originally introduce by adding new services and features. Do you know everything you need to about Azure? This course will teach you about the Azure App Service, monitoring and application insights, DevOps, and Team Services.

it_saigeDeveloperCommented:
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-
it_saigeDeveloperCommented:
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-
Scott BaldridgeAuthor 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.
it_saigeDeveloperCommented:
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-
it_saigeDeveloperCommented:
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-

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Scott BaldridgeAuthor Commented:
Thank you! I'm going to give it a go!
Jacques Bourgeois (James Burger)PresidentCommented:
@it_saige

Where did you get the documentation for the EnumValueName attribute? I cannot find it anywhere, even by googling it.
Scott BaldridgeAuthor Commented:
WOW! that is the way to go! Works perfectly!
it_saigeDeveloperCommented:
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-
it_saigeDeveloperCommented:
Glad that worked out for you Earnie.

-saige-
p_davisCommented:
@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.
p_davisCommented:
i know i shouldn't post a link here but...

http://www.codeproject.com/Articles/11130/String-Enumerations-in-C
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
C#

From novice to tech pro — start learning today.