如何在ICollection类型的属性上使用反射?

时间:2010-10-28 14:29:11

标签: c# reflection icollection

我有一个方法,我传入两个具有相同属性名称的对象,并且我使用Reflection从一个对象获取值并在另一个对象上设置值。我的问题是,当我遇到一个属性是一个集合时,原来是EntityCollection,并且得到的一个是ObservableCollection,当我尝试设置值时,我显然会抛出一个转换错误。

那我该怎么办呢?我认为一种方法是获取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);
        }
    }
}

1 个答案:

答案 0 :(得分: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();
    }
}