2010-10-28 74 views
0

我有一個方法,我傳遞兩個對象,它們具有相同的屬性名稱,我使用Reflection從一個對象獲取值並在另一個對象上設置值。我遇到的問題是,當我遇到一個屬性是一個集合,原始的是EntityCollection,設置的是ObservableCollection,當我嘗試設置值時,我顯然會拋出一個轉換錯誤。如何在ICollection類型的屬性上使用反射?

那麼我會怎麼做呢?我認爲一種方法是獲取EntityCollection屬性的實例,並在循環中使用Activator.CreateInstance()向ObservableCollection添加一個新項目。但是我遇到了另一個如何獲得原始實例的問題。

我會非常感謝這個困境的一些見解。我將發佈我正在使用的方法的代碼。目前它不工作,主要是我發佈它僅供參考。所以請不要指出明顯的。提前致謝。

protected void SetValues(Object thisObject, Object entity) 
{ 
    PropertyInfo[] properties = entity.GetType().GetProperties(); 
    foreach (PropertyInfo property in properties) 
    { 
     var value = property.GetValue(entity, null); 
     var thisObjectsProperty = thisObject.GetType().GetProperty(property.Name); 

     if (thisObjectsProperty != null && value != null) 
     { 
      if (thisObjectsProperty.PropertyType.GetInterface("ICollection", true) != null    && thisObjectsProperty.PropertyType.GetGenericArguments().Count() > 0) 
      { 
       Type genericType = thisObjectsProperty.PropertyType.GetGenericArguments()[0]; 
       Type entityCollectionType = property.PropertyType; 
       Type thisCollectionType = thisObjectsProperty.PropertyType; 

       IList entityCollection = (IList)Activator.CreateInstance(entityCollectionType.MakeGenericType(genericType)); 
       IList observableCollection = (IList)Activator.CreateInstance(thisCollectionType.MakeGenericType(genericType)); 

       foreach (var item in entityCollection) 
       { 
        String typeString = String.Concat("RulesGenerator.DependencyObjects.", genericType.Name); 
        Type newItemType = Type.GetType(typeString, false, true); 
        if (newItemType != null) 
        { 
         var newItem = Activator.CreateInstance(newItemType); 
         SetValues(newItem, item); 
         observableCollection.Add(newItem); 
        } 
       } 
      } 
      else 
       thisObjectsProperty.SetValue(thisObject, value, null); 
     } 
    } 
} 
+0

是有一些原因,你不能只克隆對象? – eschneider 2010-10-28 14:42:21

+0

從未嘗試過克隆,我會盡力回覆你。謝謝。 – jhorton 2010-10-28 16:38:31

回答

0

實施ICloneable接口以提供深層複製。你應該能夠找到一些例子,但這裏是一個起點:

http://msdn.microsoft.com/en-us/library/system.icloneable%28v=VS.71%29.aspx

http://en.csharp-online.net/ICloneable

using System; 
using System.Collections; 
using System.Collections.Generic; 
using System.Data; 
using System.Diagnostics; 


public class testMain : ICloneable 
{ 

    private string m_TestProp; 

    private List<Record> m_Items = new List<Record>(); 
    public string TestProp 
    { 
     get { return m_TestProp; } 
     set { m_TestProp = value; } 
    } 

    public List<Record> Items 
    { 
     get { return m_Items; } 
    } 


    public object Clone() 
    { 

     testMain cpy =(testMain) this.MemberwiseClone(); 

     foreach (Record rec in this.Items) 
     { 
      Record recCpy = (Record)rec.Clone(); 
      cpy.Items.Add(recCpy); 
     } 

     return cpy; 
    } 

} 

public class Record : ICloneable 
{ 

    private string m_TestProp; 

    public string TestProp 
    { 
     get { return m_TestProp; } 
     set { m_TestProp = value; } 
    } 

    public object Clone() 
    { 
     return this.MemberwiseClone(); 
    } 
} 
+0

看了它之後,當我調用PropertyInfo實例的GetValue方法時,它給了我一個EntityCollection的實例。問題是GetValue返回一個Object類型。所以現在我的問題是,當通用參數T需要動態設置時,如何將對象投射到EntityCollection 。類似於...,類型genericEntityType = property.PropertyType.GetGenericArguments()[0]; var ec = property.GetValue()as EntityCollection ; – jhorton 2010-10-28 17:56:46

+0

ICloneable是一種更好的方法.. – eschneider 2010-10-28 18:12:56

+0

這並不是說你的方法不能工作(它可以),只是這是複製對象和維護更容易的常用方法。 – eschneider 2010-10-28 18:30:00