My enum structure is this
public enum UserRole
{
Administrator = "Administrator",
Simple_User = "Simple User",
Paid_User = "Paid User"
}
Now i want to read this enum value by using its name suppose
String str = UserRole.Simple_User;
it gives me "Simple User" in str instead of "Simple_User"
How we can do this???
You can do a friendly description like so:
public enum UserRole
{
[Description("Total administrator!!1!one")]
Administrator = 1,
[Description("This is a simple user")]
Simple_User = 2,
[Description("This is a paid user")]
Paid_User = 3,
}
And make a helper function:
public static string GetDescription(Enum en)
{
Type type = en.GetType();
MemberInfo[] info = type.GetMember(en.ToString());
if (info != null && info.Length > 0)
{
object[] attrs = info[0].GetCustomAttributes(typeof(DescriptionAttribute), false);
if (attrs != null && attrs.Length > 0)
{
return ((DescriptionAttribute)attrs[0]).Description;
}
}
return en.ToString();
}
And use it like:
string description = GetDescription(UserRole.Administrator);
Okay so by now you know that enum really is a list of numbers that you can give a handy string handle to like:
public enum ErrorCode
{
CTCLSM = 1,
CTSTRPH = 2,
FBR = 3,
SNF = 4
}
Also, as #StriplingWarrior showed, you can go so far by getting the enum string name and replacing underscores etc. But what I think you want is a way of associating a nice human string with each value. How about this?
public enum ErrorCode
{
[EnumDisplayName("Cataclysm")]
CTCLSM = 1,
[EnumDisplayName("Catastrophe")]
CTSTRPH = 2,
[EnumDisplayName("Fubar")]
FBR = 3,
[EnumDisplayName("Snafu")]
SNF = 4
}
Okay there's probably something in System.ComponentModel that does this - let me know. The code for my solution is here:
[AttributeUsage(AttributeTargets.Field)]
public class EnumDisplayNameAttribute : System.Attribute
{
public string DisplayName { get; set; }
public EnumDisplayNameAttribute(string displayName)
{
DisplayName = displayName;
}
}
And the funky Enum extension that makes it possible:
public static string PrettyFormat(this Enum enumValue)
{
string text = enumValue.ToString();
EnumDisplayNameAttribute displayName = (EnumDisplayNameAttribute)enumValue.GetType().GetField(text).GetCustomAttributes(typeof(EnumDisplayNameAttribute), false).SingleOrDefault();
if (displayName != null)
text = displayName.DisplayName;
else
text = text.PrettySpace().Capitalize(true);
return text;
}
So to get the human-friendly value out you could just do ErrorCode.CTSTRPH.PrettyFormat()
Hmm, enums can't have string values. From MSDN's Enum page:
An enumeration is a set of named constants whose underlying type is any integral type except Char.
To get the string version of the enum use the Enum's ToString method.
String str = UserRole.Simple_User.ToString("F");
I'm a little confused by your question, because C# doesn't allow you to declare enums backed by strings. Do you mean that you want to get "Simple User", but you're getting "Simple_User" instead?
How about:
var str = UserRole.Simple_User.ToString().Replace("_", " ");
You can do this by attribute, but really I think using an enum like this is possibly the wrong way to go about things.
I would create a user role interface that exposes a display name property, then implement that interface with a new class for each role, this also let's you add more behaviour in the future.
Or you could use an abstract class so any generic behaviour doesn't get duplicated...
Related
This is different from questions like below
How to tell if an enum property has been set? C#
I am working on creating WCF Rest service using existing DataContract classes. I cannot change property datatypes like enum to enum? and also cannot add new option in my enum like undefined, none, or by default set anything since if I do anyone of these changes it will be firm wide impact and many applications depend on it.
Normally people call my WCF REST Service using applications like POSTMAN where they send in json data like below in which Gender is an enum with Male, Female, Transgender, etc. If they do not send it my service throws exception and I want to add validation logic to check whether enum is null or not when QA scall my service using POSTMAN and send JSON data even though it is not nullable and also do not have any None, Null options in my enum? If it is NULL I want to send ArgumentNullException back to callers with nice message. I want to handle this situation gracefully.
public enum Gender
{
Male = 0,
Female = 1,
Transgender = 2
}
Below is good
{
"Name" : "XXX"
"Gender" : "1"
}
Below throws error
{
"Name" : "XXX"
"Gender" : ""
}
SOLUTION:
Thanks to p.s.w.g for pointing in correct direction and I marked his answer below. I am using Newtonsoft so I did like below
string stringfydata = Newtonsoft.Json.JsonConvert.SerializeObject(requestGender);
if(string.IsNullOrEmpty(stringfydata))
{
throw new ArgumentNullException("Gender value cannot be NULL or Empty.");
}
Other than the obvious option of warping the enum in a class, which might not work in your specific situation, you can set the enum variable to a integer out of the enum range. After that, you can then check to see if the integer is defined within the enum.
Since C# does not check enumerations, you can do the following:
public enum Gender
{
Male = 0,
Female = 1,
Transgender = 2
}
public int HandleGender(string strJsonGender){
if (strJsonGender == "")
{
return -1;
}
else {
// Get int representation of the gender
return (int)((Gender)Enum
.Parse(typeof(Gender),
strJsonGender, true));
}
}
public void MainMethod(string strJsonGender) {
Gender gVal;
int iVal = HandleGender(strJsonGender);
if (Enum.IsDefined(typeof(Gender), iVal))
{
// Handle if the an actual gender was specified
gVal = (Gender)iVal;
}
else {
// Handle "null" logic
}
Note: the answers below use DataContracts since you've indicated in your question, but similar solutions exist for Json.Net serialization.
You can use [DataMember(EmitDefaultValue = false)] to ignore cases where Gender is not specified at all. In this case, the value that's returned will be whatever enum member is assigned a value of 0 (note that if no member has that value, you'll still get a value of 0, which could be useful for you).
[DataContract]
class Person
{
[DataMember]
public string Name { get; set; }
[DataMember(EmitDefaultValue = false)]
public Gender Gender { get; set; }
}
void Main()
{
var json = "{\"Name\": \"XXX\"}";
var ser = new DataContractJsonSerializer(typeof(Person));
var obj = ser.ReadObject(new MemoryStream(Encoding.UTF8.GetBytes(json)));
obj.Dump(); // Person { Name = "XXX", Gender = Male }
}
To handle cases where an empty string is provided instead of a valid value or no value at all, you can use this hacky little trick:
[DataContract]
class Person
{
[DataMember]
public string Name { get; set; }
[IgnoreDataMember]
public Gender Gender
{
get
{
if (GenderValue.GetType() == typeof(string))
{
Enum.TryParse((string)GenderValue, out Gender result);
return result;
}
return (Gender)Convert.ToInt32(GenderValue);
}
set
{
GenderValue = value;
}
}
[DataMember(Name = "Gender", EmitDefaultValue = false)]
private object GenderValue { get; set; }
}
void Main()
{
var json = "{\"Name\": \"XXX\", \"Gender\": \"\"}";
var ser = new DataContractJsonSerializer(typeof(Person));
var obj = ser.ReadObject(new MemoryStream(Encoding.UTF8.GetBytes(json)));
obj.Dump(); // Person { Name = "XXX", Gender = Male }
}
However, this is somewhat awkward and can be easily abused. I'd recommend caution with this approach. As others have mentioned, we typically want to throw errors whenever invalid values are provided to a function / API. By 'failing fast' you let the user attempting to use the API know that they've constructed a request that's likely to produce unexpected results at some point.
In C#, I have used Enum to get the drop down values:
class Enum
{
public enum Fields
{
AssignedTo = "Assigned To",
CloseReason = "Close Reason",
CustomerId = "Customer ID",
CustomerName = "Customer Name",
CompanyID = "Company ID",
CompanyName = "Company Name",
}
}
When I build the solution. I am getting the error: cannot implicitly convert type 'string' to 'int'.
I have removed the double quotes but still it shows the same error. What do I do wrong?
In C# string are not allowed types for enums.
Quote from MSDN https://msdn.microsoft.com/en-us/library/sbbt4032.aspx
The approved types for an enum are byte, sbyte, short, ushort, int,
uint, long, or ulong
If will have to do some kind of conversion (i.e. using [DisplayName] attribute) to use enum in dropdown.
i am not sure if it is because you are trying to display string to the enum then is because enum only use int 16 and 32 so we have to create an extension to make it show strings and then use the int value to call it
using System.Reflection;
public static class EnumExtensions
{
public static string DisplayName(this Enum value)
{
FieldInfo field = value.GetType().GetField(value.ToString());
EnumDisplayNameAttribute attribute
= Attribute.GetCustomAttribute(field, typeof(EnumDisplayNameAttribute))
as EnumDisplayNameAttribute;
return attribute == null ? value.ToString() : attribute.DisplayName;
}
}
public class EnumDisplayNameAttribute : Attribute
{
private string _displayName;
public string DisplayName
{
get { return _displayName; }
set { _displayName = value; }
}
}
class Enum
{
public enum Fields
{
[EnumDisplayName(DisplayName = "Assigned To"
AssignedTo,
[EnumDisplayName(DisplayName = "Close Reason"
CloseReason,
[EnumDisplayName(DisplayName = "Customer ID"
CustomerId,
[EnumDisplayName(DisplayName = "Customer Name"
CustomerName,
[EnumDisplayName(DisplayName = "Company ID"
CompanyID,
[EnumDisplayName(DisplayName = "Company Name"
CompanyName ,
}
}
just like i did for my group description for listview
this is syntactically invalid in c#
https://msdn.microsoft.com/en-us/library/sbbt4032.aspx
you will need a workaround to create string enum in c#
https://www.google.com/?gfe_rd=cr&ei=sBwXV_XZDKO_wQOjmaqABw&gws_rd=ssl#q=string+enum+in+c%23
It is giving this error because by default the enum expects you to assign an integer value to the fields inside an enum.
public enum Fields
{
AssignedTo = 1,
CloseReason = 2,
CustomerId = 3,
CustomerName = 4,
CompanyID = 5,
CompanyName = 6
}
If you skip the assigning part , it will by default start assign the fields starting from integer 0.
I do not think you want to be using enum for a drop down. Try looking into Dictionary or DataTable or some other structures. Maybe we could help if you give us more detail about what exactly are you trying to do.
EDIT: Here is a simple example of using List<string> as data source for ComboBox
List<string> dsList = new List<string>();
dsList.Add("Assigned To");
dsList.Add("Close Reason");
dsList.Add("Customer ID");
dsList.Add("Customer Name");
dsList.Add("Company ID");
dsList.Add("Company Name");
comboBox1.DataSource = dsList;
Also, you can dynamicaly change the List based on what options you want to display to the user
I know following syntax is possible with enum, and one can get value by parsing it in int or char.
public enum Animal { Tiger=1, Lion=2 }
public enum Animal { Tiger='T', Lion='L' }
Although following syntax is also right
public enum Anumal { Tiger="TIG", Lion="LIO"}
How do I get the value in this case? If I convert it using ToString(), I get the KEY not the VALUE.
If you really insist on using enum to do this, you can do it by having a Description attribute and getting them via Reflection.
public enum Animal
{
[Description("TIG")]
Tiger,
[Description("LIO")]
Lion
}
public static string GetEnumDescription(Enum value)
{
FieldInfo fi = value.GetType().GetField(value.ToString());
DescriptionAttribute[] attributes =
(DescriptionAttribute[])fi.GetCustomAttributes(
typeof(DescriptionAttribute),
false);
if (attributes != null &&
attributes.Length > 0)
return attributes[0].Description;
else
return value.ToString();
}
Then get the value by string description = GetEnumDescription(Animal.Tiger);
Or by using extension methods:
public static class EnumExtensions
{
public static string GetEnumDescription(this Enum value)
{
FieldInfo fi = value.GetType().GetField(value.ToString());
DescriptionAttribute[] attributes =
(DescriptionAttribute[])fi.GetCustomAttributes(
typeof(DescriptionAttribute),
false);
if (attributes != null &&
attributes.Length > 0)
return attributes[0].Description;
else
return value.ToString();
}
}
Then use it by string description = Animal.Lion.GetEnumDescription();
You can't use strings in enums. Use one or multiple dictionaries istead:
Dictionary<Animal, String> Deers = new Dictionary<Animal, String>
{
{ Animal.Tiger, "TIG" },
{ ... }
};
Now you can get the string by using:
Console.WriteLine(Deers[Animal.Tiger]);
If your deer numbers are in line ( No gaps and starting at zero: 0, 1, 2, 3, ....) you could also use a array:
String[] Deers = new String[] { "TIG", "LIO" };
And use it this way:
Console.WriteLine(Deers[(int)Animal.Tiger]);
Extension method
If you prefer not writing every time the code above every single time you could also use extension methods:
public static String AsString(this Animal value) => Deers.TryGetValue(value, out Animal result) ? result : null;
or if you use a simple array
public static String AsString(this Animal value)
{
Int32 index = (Int32)value;
return (index > -1 && index < Deers.Length) ? Deers[index] : null;
}
and use it this way:
Animal myAnimal = Animal.Tiger;
Console.WriteLine(myAnimal.AsString());
Other possibilities
Its also possible to do the hole stuff by using reflection, but this depends how your performance should be ( see aiapatag's answer ).
That is not possible, the value of the enum must be mapped to a numeric data type. (char is actually a number wich is wirtten as a letter)
However one solution could be to have aliases with same value such as:
public enum Anumal { Tiger=1, TIG = 1, Lion= 2, LIO=2}
Hope this helps!
This isn't possible with Enums. http://msdn.microsoft.com/de-de/library/sbbt4032(v=vs.80).aspx
You can only parse INT Values back.
I would recommend static members:
public class Animal
{
public static string Tiger="TIG";
public static string Lion="LIO";
}
I think it's easier to handle.
As DonBoitnott said in comment, that should produce compile error. I just tried and it does produce. Enum is int type actually, and since char type is subset of int you can assign 'T' to enum but you cannot assign string to enum.
If you want to print 'T' of some number instead of Tiger, you just need to cast enum to that type.
((char)Animal.Tiger).ToString()
or
((int)Animal.Tiger).ToString()
Possible alternative solution:
public enum SexCode : byte { Male = 77, Female = 70 } // ascii values
after that, you can apply this trategy in your class
class contact {
public SexCode sex {get; set;} // selected from enum
public string sexST { get {((char)sex).ToString();}} // used in code
}
I have an enum annotated with EnumMember to facilitate JSON.NET serialization similar to the following:
[DataContract]
[JsonConverter(typeof(StringEnumConverter))]
public enum Status
{
[EnumMember(Value = "NOT_ADMITTED")]
NotAdmitted,
[EnumMember(Value = "ADMITTED")]
Admitted
}
Now, independent of the JSON.NET serialization I'd like to I'd like to convert instances of the enum to a string while abiding by the EnumMember annotations in the data contract, e.g.:
aStatusInstance.ToString() == "NOT_ADMITTED".
Any suggestions? Thanks!
Update: My Solution
I modified the code in the accepted answer to create an extension method to retrieve the EnumMember Value:
public static string GetEnumMemberValue(this Enum enumValue)
{
var type = enumValue.GetType();
var info = type.GetField(enumValue.ToString());
var da = (EnumMemberAttribute[])(info.GetCustomAttributes(typeof(EnumMemberAttribute), false));
if (da.Length > 0)
return da[0].Value;
else
return string.Empty;
}
I would use the Description Attribute and decorate the enum with the same value as the EnumMember:
[DataContract]
[JsonConverter(typeof(StringEnumConverter))]
public enum Status
{
[EnumMember(Value = "NOT_ADMITTED")]
[Description("NOT_ADMITTED")]
NotAdmitted,
[EnumMember(Value = "ADMITTED")]
[Description("ADMITTED")]
Admitted
}
You can use this code snippet to parse it. This is written as an extension of the Enum class:
public static string GetDescription(this Enum enumValue)
{
Type type = enumValue.GetType();
FieldInfo info = type.GetField(enumValue.ToString());
DescriptionAttribute[] da = (DescriptionAttribute[])(info.GetCustomAttributes(typeof(DescriptionAttribute), false));
if (da.Length > 0)
return da[0].Description;
else
return string.Empty;
}
You can then compare it with the following:
aStatusInstance.GetDescription() == "NOT_ADMITTED"
I want to create string ENUM in c#.
Basically i wan't to set form name in Enum. When i open form in main page that time i want to switch case for form name and open that particular form.
I know ENUM allows only integer but i want to set it to string.
Any Idea?
Enum cannot be string but you can attach attribute and than you can read the value of enum as below....................
public enum States
{
[Description("New Mexico")]
NewMexico,
[Description("New York")]
NewYork,
[Description("South Carolina")]
SouthCarolina
}
public static string GetEnumDescription(Enum value)
{
FieldInfo fi = value.GetType().GetField(value.ToString());
DescriptionAttribute[] attributes =
(DescriptionAttribute[])fi.GetCustomAttributes(
typeof(DescriptionAttribute),
false);
if (attributes != null &&
attributes.Length > 0)
return attributes[0].Description;
else
return value.ToString();
}
here is good article if you want to go through it : Associating Strings with enums in C#
As everyone mentioned, enums can't be strings (or anything else except integers) in C#. I'm guessing you come from Java? It would be nice if .NET had this feature, where enums can be any type.
The way I usually circumvent this is using a static class:
public static class MyValues
{
public static string ValueA { get { return "A"; } }
public static string ValueB { get { return "B"; } }
}
With this technique, you can also use any type. You can call it just like you would use enums:
if (value == MyValues.ValueA)
{
// do something
}
Do this:
private IddFilterCompareToCurrent myEnum =
(IddFilterCompareToCurrent )Enum.Parse(typeof(IddFilterCompareToCurrent[1]),domainUpDown1.SelectedItem.ToString());
[Enum.parse] returns an Object, so you need to cast it.
Im not sure if I understood you corectly but I think you are looking for this?
public enum State { State1, State2, State3 };
public static State CurrentState = State.State1;
if(CurrentState == State.State1)
{
//do something
}
I don't think that enums are the best solution for your problem. As others have already mentionde, the values of an enum can only be integer values.
You could simply use a Dictionary to store the forms along with their name like:
Dictionary<string, Form> formDict = new Dictionary<string, Form>();
private void addFormToDict(Form form) {
formDict[form.Name] = form;
}
// ...
addFormToDict(new MyFirstForm());
addFormToDict(new MySecondForm());
// ... add all forms you want to display to the dictionary
if (formDict.ContainsKey(formName))
formDict[formName].Show();
else
MessageBox.Show(String.Format("Couldn't find form '{0}'", formName));
Either make the names of the Enum members exactly what you want and use .ToString(),
Write a function like this ...
string MyEnumString(MyEnum value)
{
const string MyEnumValue1String = "any string I like 1";
const string MyEnumValue2String = "any string I like 2";
...
switch (value)
{
case MyEnum.Value1:
return MyEnumValue1String;
case MyEnum.Value2:
return MyEnumValue2String;
...
}
}
Or use some dictionary or hash set of values and strings instead.
string enums don't exist in C#. See this related question.
Why don't you use an int (default type for enums) instead of a string?