简体   繁体   中英

PropertyInfo.GetValue returns enumeration constant name instead of value

i'm building a serialization component that uses reflection to build the serialized data, but i'm getting weird results from enumerated properties:

enum eDayFlags
{
    Sunday = 1,
    Monday = 2,
    Tuesday = 4,
    Wednesday = 8,
    Thursday = 16,
    Friday = 32,
    Saturday = 64
}

public eDayFlags DayFlags { get; set; }

Now for the real test

Obj Test = new Obj();
Test.DayFlags = eDayFlags.Friday;

Output of serialization is then:

DayFlags=Friday

But if i set two flags in my variable:

Obj Test = new Obj();
Test.DayFlags = eDayFlags.Friday;
Test.DayFlags |= eDayFlags.Monday;

Output of serialization is then:

DayFlags=34

What i am doing in the serialization component is pretty simple:

//Loop each property of the object
foreach (var prop in obj.GetType().GetProperties())
{

     //Get the value of the property
     var x = prop.GetValue(obj, null).ToString();

     //Append it to the dictionnary encoded
     if (x == null)
     {
          Properties.Add(HttpUtility.UrlEncode(prop.Name) + "=null");
     }
     else
     {
          Properties.Add(HttpUtility.UrlEncode(prop.Name) + "=" + HttpUtility.UrlEncode(x.ToString()));
     }
}

Can anyone tell me how to get the real value of the variable from PropertyInfo.GetValue even if it's an enumeration and there is only one value?

Thanks

You are getting the real value out - it's just the conversion to a string which isn't doing what you expect. The value returned by prop.GetValue will be the boxed eDayFlags value.

Do you want the numeric value from the enum? Cast it to an int . You're allowed to unbox an enum value to its underlying type.

Note that your enum - which should probably be called Days - ought to have [Flags] applied to it, given that it is a flags enum.

It is the expected behavior.

You did not set the Flags attribute on your enum, so .ToString() returns the string representation of the enum casted as its underlying type ( int per default).

Adding [Flags] will force your .ToString() to return your expected value, ie "Monday, Friday"


If you decompile the Enum class, you'll see code that looks like the following in the ToString() implementation:

//// If [Flags] is NOT present
if (!eT.IsDefined(typeof (FlagsAttribute), false))
//// Then returns the name associated with the value, OR the string rep. of the value
//// if the value has no associated name (which is your actual case)
    return Enum.GetName((Type) eT, value) ?? value.ToString();
else
//// [Flags] defined, so return the list of set flags with
//// a ", " between
    return Enum.InternalFlagsFormat(eT, value);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM