动态数组对象

时间:2015-11-25 04:27:36

标签: c# .net expandoobject

我正在尝试构建一个将对象转换为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"} }
        };

我得到以下内容:VS Watch

正如您所看到的,顶部的匿名对象有一个学生数组,但转换后的ExpandoObject没有。

有没有人对我如何更改代码以在ExpandoObject中添加对数组/列表的支持有任何见解?

谢谢!

1 个答案:

答案 0 :(得分:1)

创建像

这样的对象时
var person = new
            {
                FirstName = "Test",
                LastName = new List<Person>() { new Person()
                {
                    FirstName = "Tes2"                    
                } }
            };

LastName是一个通用列表,Property.PropertyType.IsArray在该情况下返回false。因此,您尝试添加

的逻辑不会对您的“数组/列表”进行处理
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)原始值的逻辑内再次检查,你做到了,这是递归的停止条件之一。下面是相同的代码,区别于我提到

 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;
        }