动态数组对象
dynamic Array object
我正在尝试构建一个将对象转换为 ExpandoObjects 的通用方法,我可以处理所有情况,除非其中一个属性是数组。
public static ExpandoObject ToExpando(this object AnonymousObject) {
dynamic NewExpando = new ExpandoObject();
foreach (var Property in AnonymousObject.GetType().GetProperties()) {
dynamic Value;
if (IsPrimitive(Property.PropertyType)) {
Value = Property.GetValue(AnonymousObject);
} else if (Property.PropertyType.IsArray) {
dynamic ArrayProperty = new List<dynamic>();
var ArrayElements = (Array)Property.GetValue(AnonymousObject);
for (var i = 0; i < ArrayElements.Length; i++) {
var Element = ArrayElements.GetValue(i);
if (IsPrimitive(Element.GetType())) {
ArrayProperty.Add(Element);
} else {
ArrayProperty.Add(ToExpando(Element));
}
}
Value = ArrayProperty;//.ToArray();
} else {
Value = ToExpando(Property.GetValue(AnonymousObject));
}
((IDictionary<string, object>) NewExpando)[Property.Name] = Value;
}
return NewExpando;
}
private static bool IsPrimitive(System.Type type) {
while (type.IsGenericType && type.GetGenericTypeDefinition() == typeof (Nullable<>)) {
// nullable type, check if the nested type is simple.
type = type.GetGenericArguments()[0];
}
return type.IsPrimitive || type.IsEnum || type.Equals(typeof (string)) || type.Equals(typeof (decimal));
}
任何 属性 数组似乎都不是动态对象,当我在剃刀模板之类的东西上使用它时,数组元素和属性不可见。
例如,如果我这样做:
var EmailParams = new {
Parent = new {
Username = "User1",
},
Students = new [] {new {Username = "Student1", Password = "Pass1"} }
};
我得到以下信息:
如您所见,顶部的匿名对象有一个学生数组,但转换后的 ExpandoObject 没有。
有人知道我将如何更改代码以在 ExpandoObject 中添加对 arrays/list 的支持吗?
谢谢!
当你创建一个像
这样的对象时
var person = new
{
FirstName = "Test",
LastName = new List<Person>() { new Person()
{
FirstName = "Tes2"
} }
};
LastName 是一个通用列表,Property.PropertyType.IsArray returns 在这种情况下为 false。所以你的 "array/list" 没有被你试图添加的逻辑处理
dynamic ArrayProperty = new List<dynamic>();
var ArrayElements = (Array)Property.GetValue(AnonymousObject);
for (var i = 0; i < ArrayElements.Length; i++) {
var Element = ArrayElements.GetValue(i);
if (IsPrimitive(Element.GetType())) {
ArrayProperty.Add(Element);
} else {
ArrayProperty.Add(ToExpando(Element));
}
}
希望对您有所帮助
只是一句话,你不需要再次检查 if(Property.Property.Type.IsArray)
Primitive 值的逻辑,你做到了,这是你递归的停止条件之一。下面是相同的代码,不同之处在于我提到的
public static ExpandoObject ToExpando(this object AnonymousObject)
{
dynamic NewExpando = new ExpandoObject();
foreach (var Property in AnonymousObject.GetType().GetProperties())
{
dynamic Value;
if (IsPrimitive(Property.PropertyType))
{
Value = Property.GetValue(AnonymousObject);
}
else if (Property.PropertyType.IsArray)
{
var ArrayProperty = new List<ExpandoObject>();
var elements = Property.GetValue(AnonymousObject) as IEnumerable;
//is the same as foreach all elements calling to Expando and adding them to elemenstArray
if (elements != null)
ArrayProperty.AddRange(from object elem in elements select ToExpando(elem));
Value = ArrayProperty;
}
else
{
Value = ToExpando(Property.GetValue(AnonymousObject));
}
((IDictionary<string, object>)NewExpando)[Property.Name] = Value;
}
return NewExpando;
}
我正在尝试构建一个将对象转换为 ExpandoObjects 的通用方法,我可以处理所有情况,除非其中一个属性是数组。
public static ExpandoObject ToExpando(this object AnonymousObject) {
dynamic NewExpando = new ExpandoObject();
foreach (var Property in AnonymousObject.GetType().GetProperties()) {
dynamic Value;
if (IsPrimitive(Property.PropertyType)) {
Value = Property.GetValue(AnonymousObject);
} else if (Property.PropertyType.IsArray) {
dynamic ArrayProperty = new List<dynamic>();
var ArrayElements = (Array)Property.GetValue(AnonymousObject);
for (var i = 0; i < ArrayElements.Length; i++) {
var Element = ArrayElements.GetValue(i);
if (IsPrimitive(Element.GetType())) {
ArrayProperty.Add(Element);
} else {
ArrayProperty.Add(ToExpando(Element));
}
}
Value = ArrayProperty;//.ToArray();
} else {
Value = ToExpando(Property.GetValue(AnonymousObject));
}
((IDictionary<string, object>) NewExpando)[Property.Name] = Value;
}
return NewExpando;
}
private static bool IsPrimitive(System.Type type) {
while (type.IsGenericType && type.GetGenericTypeDefinition() == typeof (Nullable<>)) {
// nullable type, check if the nested type is simple.
type = type.GetGenericArguments()[0];
}
return type.IsPrimitive || type.IsEnum || type.Equals(typeof (string)) || type.Equals(typeof (decimal));
}
任何 属性 数组似乎都不是动态对象,当我在剃刀模板之类的东西上使用它时,数组元素和属性不可见。
例如,如果我这样做:
var EmailParams = new {
Parent = new {
Username = "User1",
},
Students = new [] {new {Username = "Student1", Password = "Pass1"} }
};
我得到以下信息:
如您所见,顶部的匿名对象有一个学生数组,但转换后的 ExpandoObject 没有。
有人知道我将如何更改代码以在 ExpandoObject 中添加对 arrays/list 的支持吗?
谢谢!
当你创建一个像
这样的对象时var person = new
{
FirstName = "Test",
LastName = new List<Person>() { new Person()
{
FirstName = "Tes2"
} }
};
LastName 是一个通用列表,Property.PropertyType.IsArray returns 在这种情况下为 false。所以你的 "array/list" 没有被你试图添加的逻辑处理
dynamic ArrayProperty = new List<dynamic>();
var ArrayElements = (Array)Property.GetValue(AnonymousObject);
for (var i = 0; i < ArrayElements.Length; i++) {
var Element = ArrayElements.GetValue(i);
if (IsPrimitive(Element.GetType())) {
ArrayProperty.Add(Element);
} else {
ArrayProperty.Add(ToExpando(Element));
}
}
希望对您有所帮助
只是一句话,你不需要再次检查 if(Property.Property.Type.IsArray)
Primitive 值的逻辑,你做到了,这是你递归的停止条件之一。下面是相同的代码,不同之处在于我提到的
public static ExpandoObject ToExpando(this object AnonymousObject)
{
dynamic NewExpando = new ExpandoObject();
foreach (var Property in AnonymousObject.GetType().GetProperties())
{
dynamic Value;
if (IsPrimitive(Property.PropertyType))
{
Value = Property.GetValue(AnonymousObject);
}
else if (Property.PropertyType.IsArray)
{
var ArrayProperty = new List<ExpandoObject>();
var elements = Property.GetValue(AnonymousObject) as IEnumerable;
//is the same as foreach all elements calling to Expando and adding them to elemenstArray
if (elements != null)
ArrayProperty.AddRange(from object elem in elements select ToExpando(elem));
Value = ArrayProperty;
}
else
{
Value = ToExpando(Property.GetValue(AnonymousObject));
}
((IDictionary<string, object>)NewExpando)[Property.Name] = Value;
}
return NewExpando;
}