当从 C# 中的动态获取 属性 时,如何检查枚举 属性?
How do I check enum property when the property is obtained from dynamic in C#?
假设我知道对象的 属性 Color
returns 枚举,如下所示:
enum ColorEnum {
Red,
Green,
Blue
};
我想检查未知类型的特定对象(我知道有 Color
属性)是否已将 Color
设置为 Red
。如果我知道对象类型,我会这样做:
ObjectType thatObject = obtainThatObject();
if( thatObject.Color == ColorEnum.Red ) {
//blah
}
问题是我没有对带有 ColorEnum
的程序集的引用,也不知道对象类型。
所以我有以下设置:
dynamic thatObject = obtainThatObject();
而且我无法转换,因为我不知道对象类型(和枚举类型)。我应该如何检查 Color
?
if( thatObject.Color.ToString() == "Red" ) {
//blah
}
确实有效,但它看起来像是我在 "The Daily WTF".
中看到的最糟糕的货物崇拜代码示例
如何正确进行检查?
如何先将颜色 属性 解析为您的枚举
if ((ColorEnum) Enum.Parse(typeof (ColorEnum), thatObject.Color.ToString()) == ColorEnum.Red)
{
// do something
}
一种可能的(非正统的)方法是:强制您的动态对象(无论它是什么对象)成为 ExpandoObject(使用此扩展方法):
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;
}
转换您获得的对象:
var obtainedObject = (object)obtainThatObject();
var myexpando = obtainedObject.ToDynamic(); // now you have an ExpandoObject
因此您可以在 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
}
}
走这条路你不必关心它是什么对象...
侧面组装中:
enum ColorEnum
{
Red,
Green,
Blue
};
我们知道红色存在,但对其他颜色一无所知。因此,我们仅使用已知值重新定义程序集中的枚举。
enum KnownColorEnum // in your assembly
{
Red
};
因此我们可以进行解析:
public static KnownColorEnum? GetKnownColor(object value)
{
KnownColorEnum color;
if (value != null && Enum.TryParse<KnownColorEnum>(value.ToString(), out color))
{ return color; }
return null;
}
示例:
// 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
{ }
假设我知道对象的 属性 Color
returns 枚举,如下所示:
enum ColorEnum {
Red,
Green,
Blue
};
我想检查未知类型的特定对象(我知道有 Color
属性)是否已将 Color
设置为 Red
。如果我知道对象类型,我会这样做:
ObjectType thatObject = obtainThatObject();
if( thatObject.Color == ColorEnum.Red ) {
//blah
}
问题是我没有对带有 ColorEnum
的程序集的引用,也不知道对象类型。
所以我有以下设置:
dynamic thatObject = obtainThatObject();
而且我无法转换,因为我不知道对象类型(和枚举类型)。我应该如何检查 Color
?
if( thatObject.Color.ToString() == "Red" ) {
//blah
}
确实有效,但它看起来像是我在 "The Daily WTF".
中看到的最糟糕的货物崇拜代码示例如何正确进行检查?
如何先将颜色 属性 解析为您的枚举
if ((ColorEnum) Enum.Parse(typeof (ColorEnum), thatObject.Color.ToString()) == ColorEnum.Red)
{
// do something
}
一种可能的(非正统的)方法是:强制您的动态对象(无论它是什么对象)成为 ExpandoObject(使用此扩展方法):
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;
}
转换您获得的对象:
var obtainedObject = (object)obtainThatObject();
var myexpando = obtainedObject.ToDynamic(); // now you have an ExpandoObject
因此您可以在 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
}
}
走这条路你不必关心它是什么对象...
侧面组装中:
enum ColorEnum
{
Red,
Green,
Blue
};
我们知道红色存在,但对其他颜色一无所知。因此,我们仅使用已知值重新定义程序集中的枚举。
enum KnownColorEnum // in your assembly
{
Red
};
因此我们可以进行解析:
public static KnownColorEnum? GetKnownColor(object value)
{
KnownColorEnum color;
if (value != null && Enum.TryParse<KnownColorEnum>(value.ToString(), out color))
{ return color; }
return null;
}
示例:
// 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
{ }