set Enums using reflection - c#

How to set Enums using reflection,
my class have enum :
public enum LevelEnum
{
NONE,
CRF,
SRS,
HLD,
CDD,
CRS
};
and in runtime I want to set that enum to CDD for ex.
How can I do it ?

Try use of class Enum
LevelEnum s = (LevelEnum)Enum.Parse(typeof(LevelEnum), "CDD");

public class MyObject
{
public LevelEnum MyValue {get;set,};
}
var obj = new MyObject();
obj.GetType().GetProperty("MyValue").SetValue(LevelEnum.CDD, null);

value = (LevelEnum)Enum.Parse(typeof(LevelEnum),"CDD");
So basically you just parse the string corresponding to the enum value that you wish to assign to the variable. This will blow if the string is not a defined member of the enum. you can check that with Enum.IsDefined(typeof(LevelEnum),input);

Related

c# 6.0 and reflection, getting value of Property Initializers

I've been trying to experiment with reflection and I have a question.
Lets say I have a class, and in this class I have a property initilized with the new feature of c# 6.0
Class MyClass()
{
public string SomeProperty{ get; set; } = "SomeValue";
}
Is there any way of getting this value, with reflection, without initilizating the class?
I know I could do this;
var foo= new MyClass();
var value = foo.GetType().GetProperty("SomeProperty").GetValue(foo);
But what I want to do is something similiar to this ;
typeof(MyClass).GetProperty("SomeProperty").GetValue();
I know I could use a field to get the value. But it needs to be a property.
Thank you.
It's just a syntax sugar.
This:
class MyClass()
{
public string SomeProperty{ get; set; } = "SomeValue";
}
will be unwrapped by compiler into this:
class MyClass()
{
public MyClass()
{
_someProperty = "SomeValue";
}
// actually, backing field name will be different,
// but it doesn't matter for this question
private string _someProperty;
public string SomeProperty
{
get { return _someProperty; }
set { _someProperty = value; }
}
}
Reflection is about metadata. There are no any "SomeValue" stored in metatada. All you can do, is to read property value in regular way.
I know I could use a field to get the value
Without instantiating an object, you can get values of static fields only.
To get values of instance fields, you, obviously, need an instance of object.
Alternatively, if you need default value of property in reflection metadata, you can use Attributes, one of it from System.ComponentModel, do the work: DefaultValue. For example:
using System.ComponentModel;
class MyClass()
{
[DefaultValue("SomeValue")]
public string SomeProperty{ get; set; } = "SomeValue";
}
//
var propertyInfo = typeof(MyClass).GetProperty("SomeProperty");
var defaultValue = (DefaultValue)Attribute.GetCustomeAttribute(propertyInfo, typeof(DefaultValue));
var value = defaultValue.Value;

Get class name of enum by its value

I have some enum
public enum MyEnum
{
Field1,
Field2
}
and pass value in function
DoSmth(MyEnum.Field1);
How can i get classname "MyEnum" in that function
void DoSmth(Enum enumArg)
{
string className = Magic(enumArg); // className = "MyEnum"
}
Note that the code you've posted doesn't compile. enum is a reserved word and cannot be used as a variable name. The following will work, however.
void DoSmth(Enum e)
{
string className = e.GetType().Name; // className = "MyEnum"
}
If you just need to check if enum is MуEnum then it's better to check as if (enum is MyEnum)
If you need type name then you need enum.GetType().Name

How to get Enum object by value in C#?

I recently encountered a case when I needed to get an Enum object by value (to be saved via EF CodeFirst), and here is my Enum:
public enum ShipmentStatus {
New = 0,
Shipped = 1,
Canceled = 2
}
So I needed to get ShipmentStatus.Shipped object by value 1.
So how could I accomplish that?
This should work, either (just casting the int value to enum type):
int _val = 1;
ShipmentStatus _item = (ShipmentStatus)_val;
Beware, that it may cause an error if that enum is not defined.
Why not use this build in feature?
ShipmentStatus shipped = (ShipmentStatus)System.Enum.GetValues(typeof(ShipmentStatus)).GetValue(1);
After some battling with Enum I created this - a universal helper class that will do what I needed - getting key by value, and more importantly - from ANY Enum type:
public static class EnumHelpers {
public static T GetEnumObjectByValue<T>(int valueId) {
return (T) Enum.ToObject(typeof (T), valueId);
}
}
So, to get Enum object ShipmentStatus.Shipped this will return this object:
var enumObject = EnumHelpers.GetEnumObjectByValue<ShipmentStatus>(1);
So basicaly you can use any Enum object and get its key by value:
var enumObject = EnumHelpers.GetEnumObjectByValue<YOUR_ENUM_TYPE>(VALUE);

Converting a string to a custom enum

I'm trying to set a custom enum property on a custom object by looking at a string value that is held in another object, but I keep getting the error "cannot reference a type through an expression."
so far I've tried
rec.Course = (CourseEnum)Enum.Parse(typeof(CourseEnum), rr.course);
where rec.Course wants a member of the CourseEnum Enumeration, and rr.course is a string.
I also tried to do a switch statement where the value of rr.course is checked (there are only certain values it can be) but get the same result
the enum is defined as follows:
public enum CourseEnum
{
[StringValue("Starters")]
Starters,
[StringValue("Main Course")]
MainCourse,
[StringValue("Desserts")]
Desserts
};
public class StringValue : System.Attribute
{
private string _value;
public StringValue(string value)
{
_value = value;
}
public string Value
{
get { return _value; }
}
}
public static class StringEnum
{
public static string GetStringValue(Enum value)
{
string output = null;
Type type = value.GetType();
//Check first in our cached results...
//Look for our 'StringValueAttribute'
//in the field's custom attributes
FieldInfo fi = type.GetRuntimeField(value.ToString());
StringValue[] attrs =
fi.GetCustomAttributes(typeof(StringValue),
false) as StringValue[];
if (attrs.Length > 0)
{
output = attrs[0].Value;
}
return output;
}
}
I can see in your code that your using Enum.Parse with CourseEnum and it should be recipeCourse I presume.
I can't spot any place in your sample code where4 CourseEnum is defined.
A #Hans Kesting said, the answer was here: Why can not reference a type through an expression?
The problem was using a field that has an enum type with the enum type itself.

Set one enum equal to another

I have 2 enums in 2 different objects. I want to set the enum in object #1 equal to the enum in object #2.
Here are my objects:
namespace MVC1 {
public enum MyEnum {
firstName,
lastName
}
public class Obj1{
public MyEnum enum1;
}
}
namespace MVC2 {
public enum MyEnum {
firstName,
lastName
}
public class Obj2{
public MyEnum enum1;
}
}
I want to do this, but this wont compile:
MVC1.Obj1 obj1 = new MVC1.Obj1();
MVC2.Obj2 obj2 = new MVC2.Obj2();
obj1.enum1 = obj2.enum1; //I know this won't work.
How do I set the enum in Obj1 equal to the enum in Obj2? Thanks
Assuming that you keep them the same, you can cast to/from int:
obj1.enum1 = (MVC1.MyEnum)((int)obj2.enum1);
Enums have an underlying integer type, which is int (System.Int32) by default, but you can explicitly specify it too, by using "enum MyEnum : type".
Because you're working in two different namespaces, the Enum types are essentially different, but because their underlying type is the same, you can just cast them:
obj1.enum1 = (MVC1.MyEnum) obj2.enum1;
A note: In C# you have to use parentheses for function calls, even when there aren't any parameters. You should add them to the constructor calls.
Best way to do it is check if it's in range using Enum.IsDefined:
int one = (int)obj2.enum1;
if (Enum.IsDefined(typeof(MVC1.MyEnum), one )) {
obj1.enum1 = (MVC1.MyEnum)one;
}
obj1.enum1 = (MVC1.MyEnum) Enum.Parse(typeof(MVC1.MyEnum),
((int)obj2.enum1).ToString());
or
int one = (int)obj2.enum1;
obj1.enum1 = (MVC1.MyEnum)one;

Categories