2015-11-25 57 views
0

我想構建一個通用的方法來將對象轉換爲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中數組/列表的支持?

謝謝!

+0

的區別相同的代碼也許你需要這個項目:https://github.com/chsword/jdynamic – chsword

回答

1

當你創建了

var person = new 
      { 
       FirstName = "Test", 
       LastName = new List<Person>() { new Person() 
       { 
        FirstName = "Tes2"      
       } } 
      }; 

姓氏是一個通用的列表和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; 
     } 
+0

感謝您的答覆Zinov。我實際上在列表中顯式調用.ToArray(),所以不應該成爲問題。在調試時我已經確認Property.PropertyType.IsArray實際上是真的。 –

+0

你可以把你的例子的輸入數據? – Zinov

+0

我剛剛添加了一個示例 –