简体   繁体   中英

How do I check enum property when the property is obtained from dynamic in C#?

Suppose I know that property Color of an object returns an enumeration that looks like this one:

enum ColorEnum {
   Red,
   Green,
   Blue
};

and I want to check that a specific object of unknown type (that I know has Color property) has Color set to Red . This is what I would do if I knew the object type:

ObjectType thatObject = obtainThatObject();
if( thatObject.Color == ColorEnum.Red ) {
   //blah
}

The problem is I don't have a reference to the assembly with ColorEnum and don't know the object type.

So instead I have the following setup:

dynamic thatObject = obtainThatObject();

and I cannot cast because I don't know the object type (and the enum type). How should I check the Color ?

if( thatObject.Color.ToString() == "Red" ) {
    //blah
}

does work but it looks like the worst examples of cargo cult code I've seen in "The Daily WTF".

How do I do the check properly?

How about parsing the Color property to your enum first

if ((ColorEnum) Enum.Parse(typeof (ColorEnum), thatObject.Color.ToString()) == ColorEnum.Red)
{
    // do something
}

In the side assembly:

enum ColorEnum
{
    Red,
    Green,
    Blue
};

We know that Red exists, but nothing about other colors. So we redefine the enum in our assembly with known values only.

enum KnownColorEnum // in your assembly
{
    Red
};

Therefore we can perform parsing:

public static KnownColorEnum? GetKnownColor(object value)
{
    KnownColorEnum color;

    if (value != null && Enum.TryParse<KnownColorEnum>(value.ToString(), out color))
    { return color; }

    return null;
}

Examples:

// thatObject.Color == ColorEnum.Red
// or
// thatObject.Color == "Red"
if (GetKnowColor(thatObject.Color) == KnownColorEnum.Red) // true
{ }

// thatObject.Color == ColorEnum.Blue
if (GetKnowColor(thatObject.Color) == KnownColorEnum.Red) // false
{ }

One possible (unorthodox) way is: Force your dynamic object (whatever object it is) to be a ExpandoObject (with this extension method):

    public static dynamic ToDynamic(this object value)
    {
        IDictionary<string, object> expando = new ExpandoObject();

        foreach (PropertyDescriptor property in TypeDescriptor.GetProperties(value.GetType()))
            expando.Add(property.Name, property.GetValue(value));

        return expando as ExpandoObject;
    }

Convert your obtainedObject:

var obtainedObject = (object)obtainThatObject();
var myexpando = obtainedObject.ToDynamic(); // now you have an ExpandoObject

So you can get the properties in an IDictionary

IDictionary<string, object> dictionary= (IDictionary<string, object>) myexpando;
if(dictionary.ContainsKey("Color"))
{
    var myValue = dictionary["Color"];
    string color = myValue.ToString();
    if(color == "Green")
    {
         // blah
    }
}

going this way you don't have to care what object it is...

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