How can i have a c# enum that if i chose to string it returns a different string, like in java it can be done by
public enum sample{
some, other, things;
public string toString(){
switch(this){
case some: return "you choose some";
default: break;
}
}
}
Console.writeln(sample.some) will output:
you choose some
i just want my enums to return a different string when i try to call them.
To my knowledge this is not possible. However, you can write an extension method that gets some other string:
public static class EnumExtensions
{
public static string ToSampleString(this SampleEnum enum)
{
switch(enum)
{
case SampleEnum.Value1 : return "Foo";
etc.
}
}
}
Now, just call this new ToSampleString on instances of SampleEnum:
mySampleEnum.ToSampleString();
If you are unfamiliar with extension methods in C#, read more here.
Another option is to use an Description attribute above each enum value, as described here.
I would do it decoratively by creating an attribute e.g. Description and decorating the enum values with it.
e.g.
public enum Rate
{
[Description("Flat Rate")]
Flat,
[Description("Time and Materials")]
TM
}
Then use GetCustomAttributes to read/display the values. http://msdn.microsoft.com/en-us/library/system.attribute.getcustomattributes.aspx
#CodeCamper Sorry about the late response but here is some example code to read the DescriptionAttribute:
Extension method:
public static class EnumExtensions
{
public static string Description<T>(this T t)
{
var descriptionAttribute = (DescriptionAttribute) typeof (T).GetMember(t.ToString())
.First().GetCustomAttribute(typeof (DescriptionAttribute));
return descriptionAttribute == null ? "" : descriptionAttribute.Description;
}
}
Usage:
Rate currentRate = Rate.TM;
Console.WriteLine(currentRate.Description());
You want a dictionary. An enumerator enumerates (gives a number) for its values. You want a string value to be returned when you provide a string key. Try something like:
Dictionary<string, string> dictionary = new Dictionary<string, string>();
dictionary.Add("some", "you choose some");
dictionary.Add("other", "you choose other");
dictionary.Add("things", "you choose things");
Then this code:
string value = dictionary["some"];
Console.writeln(value);
will return "you choose some"
If you just want to get Enum as string you can use this method:
Enum.GetName(typeof(sample), value);
This method will return the name of Enum instead of int.
Related
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Finding the Variable Name passed to a Function in C#
The class below contains the field city.
I need to dynamically determine the field's name as it is typed in the class declaration
i.e. I need to get the string "city" from an instance of the object city.
I have tried to do this by examining its Type in DoSomething() but can't find it when examining the contents of the Type in the debugger.
Is it possible?
public class Person
{
public string city = "New York";
public Person()
{
}
public void DoSomething()
{
Type t = city.GetType();
string field_name = t.SomeUnkownFunction();
//would return the string "city" if it existed!
}
}
Some people in their answers below have asked me why I want to do this.
Here's why.
In my real world situation, there is a custom attribute above city.
[MyCustomAttribute("param1", "param2", etc)]
public string city = "New York";
I need this attribute in other code.
To get the attribute, I use reflection.
And in the reflection code I need to type the string "city"
MyCustomAttribute attr;
Type t = typeof(Person);
foreach (FieldInfo field in t.GetFields())
{
if (field.Name == "city")
{
//do stuff when we find the field that has the attribute we need
}
}
Now this isn't type safe.
If I changed the variable "city" to "workCity" in my field declaration in Person this line would fail unless I knew to update the string
if (field.Name == "workCity")
//I have to make this change in another file for this to still work, yuk!
{
}
So I am trying to find some way to pass the string to this code without physically typing it.
Yes, I could declare it as a string constant in Person (or something like that) but that would still be typing it twice.
Phew! That was tough to explain!!
Thanks
Thanks to all who answered this * a lot*. It sent me on a new path to better understand lambda expressions. And it created a new question.
Maybe you need this. Works fine.
I found this here.
static void Main(string[] args)
{
var domain = "matrix";
Check(() => domain);
Console.ReadLine();
}
static void Check<T>(Expression<Func<T>> expr)
{
var body = ((MemberExpression)expr.Body);
Console.WriteLine("Name is: {0}", body.Member.Name);
Console.WriteLine("Value is: {0}", ((FieldInfo)body.Member)
.GetValue(((ConstantExpression)body.Expression).Value));
}
Output will be:
Name is: 'domain'
Value is: 'matrix'
I know this is old question, but I was trying to achieve the same and google sent me here. After many hours I finally found a way. I hope somebody else will find this useful.
There are actually more ways to accomplish this:
static void Main(string[] args)
{
GetName(new { var1 });
GetName2(() => var1);
GetName3(() => var1);
}
static string GetName<T>(T item) where T : class
{
return typeof(T).GetProperties()[0].Name;
}
static string GetName2<T>(Expression<Func<T>> expr)
{
return ((MemberExpression)expr.Body).Member.Name;
}
static string GetName3<T>(Func<T> expr)
{
return expr.Target.GetType().Module.ResolveField(BitConverter.ToInt32(expr.Method.GetMethodBody().GetILAsByteArray(), 2)).Name;
}
The first is fastest. The last 2 are approx 20 times slower than the 1st one.
http://abdullin.com/journal/2008/12/13/how-to-find-out-variable-or-parameter-name-in-c.html
city in this case is an instance of type string. When you call .GetType() you return the actual string type, which has no knowledge at all of your particular city instance.
I'm having a hard time seeing why you can't just type "city" in the code as a string literal here, if that's what you need. Perhaps it would help if you shared what you want to use this value for and in what circumstances you will call your DoSomething() function.
At the moment, my best guess is that what you really want to do is reflect the entire Person class to get a list of the fields in that class:
public void DoSomething()
{
MemberInfo[] members = this.GetType().GetMembers();
// now you can do whatever you want with each of the members,
// including checking their .Name properties.
}
Okay, based on your edit I have some more for you.
You can find the name of fields that are decorated with your attribute at run-time like this:
Type t = typeof(Person);
foreach (MemberInfo member in t.GetMembers()
.Where(m =>
m.GetCustomAttributes(typeof(MyCustomAttribute)).Any() ) )
{
// "member" is a MemberInfo object for a Peson member that is
// decorated with your attribute
}
You can also use binding flags in the first GetMembers() call to limit it to just fields, if you want.
You mentioned "i.e. I need to get the string "city" from an instance of the object city."
Are you looking to get the field name from the value of the field.
For example:If there are 2 Person object one with city "New York" and the other with city "London", are you looking for the function to return "city". Is this what you mean by dynamic?
With your current design you will always need to compare the name of the field from the FieldInfo against a string.
What if you instead decouple this so that you hold the identifier to use for comparison purposes during reflection as part of the attribute.
Something like this:
public enum ReflectionFields
{
CITY = 0,
STATE,
ZIP,
COUNTRY
}
[AttributeUsage(AttributeTargets.Field,AllowMultiple=false)]
public class CustomFieldAttr : Attribute
{
public ReflectionFields Field { get; private set; }
public string MiscInfo { get; private set; }
public CustomFieldAttr(ReflectionFields field, string miscInfo)
{
Field = field;
MiscInfo = miscInfo;
}
}
public class Person
{
[CustomFieldAttr(ReflectionFields.CITY, "This is the primary city")]
public string _city = "New York";
public Person()
{
}
public Person(string city)
{
_city = city;
}
}
public static class AttributeReader<T> where T:class
{
public static void Read(T t)
{
//get all fields which have the "CustomFieldAttribute applied to it"
var fields = t.GetType().GetFields().Where(f => f.GetCustomAttributes(typeof(CustomFieldAttr), true).Length == 1);
foreach (var field in fields)
{
var attr = field.GetCustomAttributes(typeof(CustomFieldAttr), true).First() as CustomFieldAttr;
if (attr.Field == ReflectionFields.CITY)
{
//You have the field and you know its the City,do whatever processing you need.
Console.WriteLine(field.Name);
}
}
}
}
public class Program
{
public static void Main(string[] args)
{
PPerson p1 = new PPerson("NewYork");
PPerson p2 = new PPerson("London");
AttributeReader<PPerson>.Read(p1);
AttributeReader<PPerson>.Read(p2);
}
}
You can now freely rename _city field of Person to something else and your calling code will still work since the code using reflection is trying to identify the field using the ReflectionFields enum value set as part of initialization of the attribute set on the field.
Yes its possible !!!
Try this out...
public string DoSomething(object city)
{
return city.GetType().GetProperty("Name",typeof(string)).GetValue(city,null);
}
Two things here.
Number one, as someone above pointed out, you're getting the Type for string, not for Person. So typeof(Person).GetMembers() will get you the list of members.
Number two, and more importantly, it looks like you're misunderstanding the purpose of attributes. In general attributes are used to mark a member for specific processing or to add additional information. Here you're using the name to indicate what processing you want, and the attribute to specify parameters, which is mixing of metaphors, or something.
Abhijeet's answer is more appropriate, you mark the field as a city field, then do what you like with it. Where I disagree is that I would use different attribute classes, rather than an enumeration.
Something like:
public class MyAttribute : Attribute
{
}
[AttributeUsage(AttributeTargets.Field)]
public class MyCityAttribute : MyAttribute
{
}
[AttributeUsage(AttributeTargets.Field]
public class MyNameAttribute: MyAttribute
{
}
public class Person
{
[MyCity]
public string city = "New York";
[MyCity]
public string workCity = "Chicago";
[MyName]
public string fullName = "John Doe";
public Person()
{
}
public void DoSomething()
{
Type t = typeof(Person);
FieldInfo[] fields = t.GetFields(BindingFlags.Instance | BindingFlags.Public);
foreach (var field in fields)
{
MyAttribute[] attributes = field.GetCustomAttributes(typeof(MyAttribute));
if (attributes.Count > 0)
{
if (attributes[0] is MyCityAttribute)
{
//Dosomething for city
break;
}
if (attributes[0] is MyNameAttribute)
{
//Dosomething for names
break;
}
}
}
}
}
This would allow you to use different parameters for MyCity vs MyName that would make more sense in the context of processing each.
I think with your 'yuk' comment above, you hit the nail on the head. That you would have to change a string constant if you rename your variable is an indicator that you're doing something wrong.
t.GetField("city", BindingFlags.Public | BindingFlags.Instance);
or you can call GetFields() to get all fields
You need to call get type on the class Person. The iterate the fields of the class as in the answer below
This is not possible (I think it actually is but involes several hacks and using lambdas). If you want to store attributes about a Person and be able to get the name of the attribute easily, I suggest using a Dictionary<TKey, TValue> from the System.Collections.Generic namespace.
And you can always make public properties that wrap the dictionary.
public class Person
{
Dictionary<string, string> attributes = new Dictionary<string, string();
public string City
{
get { return attributes["city"]; }
set { attributes["city"] = value; }
}
public Person()
{
City = "New York";
}
}
And you can get a list of all attributes with attributes.Keys.
Have a look at this post as it looks similar to what you're trying to do:
Finding the variable name passed to a function
(especially Konrad Rudolph's answer) Another approach could be to just add "city" as one of the parameters in the attribute and fish that out later.
You are already looping through the collection of FieldInfo objects. Look for your attribute on those and when you find the FieldInfo that contains your attribute, you have the one you want. Then call .Name on it.
system.reflection.fieldinfo.attributes
I have a static class with constants. I am looking for options to create a method which takes a dictionary as an argument and enforcing the key to be one of the constants from the static class.Here is my static class with constants.
Here is what I am trying to do
And here is what I am trying to enforce
From the sound of it, an Enum would be more suited to what you're trying to do.
public enum MyConstants
{
FirstName,
LastName,
Title
}
public void CreateMe(Dictionary<MyConstants, string> propertyBag)
{
...
}
UPDATED
You could combine this with attributes to associate each enum with a specific string like so:
public enum PropertyNames
{
[Description("first_name")]
FirstName,
[Description("last_name")]
LastName,
[Description("title")]
Title
}
The value of each description attribute associated with each enum value could easily be grabbed via an extension method, like so:
public static class EnumExtensions
{
public static string GetDescription(this Enum value)
{
FieldInfo fieldInfo = value.GetType().GetField(value.ToString());
DescriptionAttribute[] attributes =
(DescriptionAttribute[])fieldInfo.GetCustomAttributes(
typeof(DescriptionAttribute),
false);
if (attributes != null &&
attributes.Length > 0)
return attributes[0].Description;
else
return value.ToString();
}
}
Then in your "CreateMe"-method you can get the description and value of each dictionary entry by doing something similar to this:
void CreateMe(Dictionary<PropertyNames, string> propertyBag)
{
foreach (var propertyPair in propertyBag)
{
string propertyName = propertyPair.Key.GetDescription();
string propertyValue = propertyPair.Value;
}
}
Even though this has been already answered, there is another approach, like so:
public class MyOwnEnum
{
public string Value { get; private set; }
private MyOwnEnum(string value)
{
Value = value;
}
public static readonly MyOwnEnum FirstName = new MyOwnEnum("Firstname");
public static readonly MyOwnEnum LastName = new MyOwnEnum("LastName");
}
It behaves same way like Enum and can be used in your code with same syntax. I cannot give credit to whoever came up with it, but I believe I came upon it when searching for Enums with multiple values.
With strings you can't enforce fact that keys come from limited set of vialues compile time.
Use enum or custom class (possibly with implicit conversion to string) instead.
So im new at C# and i need to know if what i want to do is possible and how heres what I have,
public static class Sempre
{
public static string Raca = "";
}
// Sempre.Raca - can use like this
Now What I want to do is set a variable like thing = "example", and after this call Sempre but with the variable something like, Sempre.thing, but because it's a variable it would actually be Sempre.example.
Example same use I want in php,
$example = mean;
$_SESSION['name'.$example];
would create $_SESSION [namemean];
You can setup your type with an indexer. http://msdn.microsoft.com/en-us/library/6x16t2tx.aspx. To use the indexer, you are required to have an instance class rather than a static one. If you really need to, you can use the singleton pattern to get "static" behavior.
Here is an example of using an indexer:
public class Sempre
{
private Dictionary<string, string> _values = new Dictionary<string, string>();
public string this[string key]
{
get { return _values[key]; }
set { _values[key] = value; }
}
}
You can use it like this:
Sempre sempre = new Sempre();
sempre["example"] = "my value";
string thing = "example";
Console.WriteLine(sempre[thing]);
Generally speaking you can not do this with objects in C# since the code is precompiled prior to runtime.
If you are specifically looking for an implementation of http session state, like you have in the PHP code example then this could be done. Session State is exposed at System.Web.SessionState.HttpSessionState and can be accessed via concatenated strings like in your example like this.
String example = "mean";
Session["name" + example] = 'bar';
//Session["namemean"] is now set to value of 'bar'
If you're only looking to do string substitution, you can also do something like this:
public class StringConstants
{
public static string YES = "yes";
public static string NO = "no";
}
then elsewhere
public void printmessage(bool value)
{
if (value)
{
Console.writeline (string.Format "I Say {0}", StringConstants.YES);
}
else
{
Console.writeline (string.Format "I Say {0}", StringConstants.NO);
}
}
Documentation on string.Format for insertions and compositions is here
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?
I've got an enum class full of command line switches for a third party app..I'm trying to make it so I can call on an item in the enum with a .ToSwitch (or whatever) so that I can make it validate the value type, spit out a formatted command-line switch with its parameter value. maybe I'm going about it wrong. After sitting here all day working on it (it's big) I'm finding it hard to let go and explore a different approach. lol any suggestions?
desired result:
Console.WriteLine(EnumClass.EnumItem.ToSwitch("option"));
would spit out: -x "option"
For a specific enum:
public enum MyEnum
{
value1 = 1,
value2 = 2,
}
public static class EnumExtensions
{
public static string ToSwitch(this MyEnum val, string option)
{
switch (val)
{
case MyEnum.value1 : return "x " + option;
case MyEnum.value2 : return "y " + option;
default: return "error";
}
}
}
Another way to do what you're talking about is with a Dictionary, which might be preferable. The keys would be the switch (or the enum value), and value would be the command format. Something like:
Dictionary<string, string> CmdFormats = new Dictionary<string, string>()
{
{ "-a", "filename" },
{ "-n", "number" }
};
I suspect that would be more maintainable than defining an enum.