2010-12-08 76 views
1

反射克隆對象假設這個屬性的對象通過特殊的限制

public int? Prop1 { get; set; } 
public string Prop2 { get; set; } 
public EntityCollection<X> Prop3 { get; set; } 
public EntityCollection<Y> Prop4 { get; set; } 
public EntityCollection<Z> Prop5 { get; set; } 

我可以複製prop1prop2用這種方法:

public static void SetProperties(PropertyInfo[] fromFields, 
              object fromRecord, 
              object toRecord) 
    { 
     PropertyInfo fromField; 

     if (fromFields == null) 
     { 
      return; 
     } 

     foreach (PropertyInfo t in fromFields) 
     { 
      fromField = t; 

      fromField.SetValue(toRecord, 
           fromField.GetValue(fromRecord, null), 
           null); 
     } 
    } 

,但我不知道怎麼每個複製prop3prop4prop5到另一個對象

編輯: 我應該Serialize對象!我做這個工作是因爲我的對象有大數據,而且這個技巧我可以複製一些數據。

有趣的是,如果我說這個問題的原始來源!我使用EF作爲ORM並通過WCFSilverlight客戶端中使用數據對象。當我發送List<Foo>WCF,它發送List<Foo>及其關係數據!和客戶死了!

+0

你關於不使用序列化的觀點在我身上丟失了;如果你想克隆一個大圖(「大數據」),你將有2 *個大圖 - 中間的序列化似乎沒有意義。 – 2010-12-08 07:28:38

+0

@Marc Gravell:只需通過反射將屬性與EntityCollection <>類型複製即可。 – 2010-12-08 10:29:16

回答

1

我會做的是使對象Serializable。然後,您可以序列化內存中的對象並將其反序列化爲新的克隆對象。

我有這兩個功能:

public static MemoryStream ToMemoryStream(object entity) 
    { 
     MemoryStream ms = new MemoryStream(); 
     BinaryFormatter formatter = new BinaryFormatter(); 

     formatter.Serialize(ms, entity); 
     return ms; 
    } 

    public static T FromMemoryStream<T>(Stream stream) 
    { 
     BinaryFormatter formatter = new BinaryFormatter(); 
     stream.Position = 0; 
     return (T)formatter.Deserialize(stream); 
    } 

與全班同學這樣

[Serializable] 
public class MyClass 
{ 
    public int? Prop1 { get; set; } 
    public string Prop2 { get; set; } 
    public EntityCollection<X> Prop3 { get; set; } 
    public EntityCollection<Y> Prop4 { get; set; } 
    public EntityCollection<Z> Prop5 { get; set; } 
} 

你現在可以在類序列化到內存中並創建從一個克隆。

public MyClass Clone() 
{ 
    var myclass = new MyClass(); 
    /* Do Some init */ 

    var ms = ToMemoryStream(myclass); 

    var myNewObject = FromMemoryStream<MyClass>(ms); 
    return myNewObject; 
} 
1

必須更換以下行

fromField.SetValue(toRecord, 
          fromField.GetValue(fromRecord, null), 
          null); 

有了這些語句,

 if (typeof(IList).IsAssignableFrom(t.PropertyType)) 
     { 
      IList fromList = fromField.GetValue(fromRecord, null); 
      IList toList = fromField.GetValue(toRecord, null); 
      foreach (var item in fromList) 
       toList.Add(item); 
     } 
     else 
     { 
      fromField.SetValue(toRecord, 
           fromField.GetValue(fromRecord, null), 
           null); 
     } 

必須更換IList的一些合適的接口可能ICollection的或其他什麼東西,將與EntityCollection工作,我沒有任何東西需要測試,所以我只發佈了這個例子。