Как использовать отражение на свойстве типа ICollection? - PullRequest
0 голосов
/ 28 октября 2010

У меня есть метод, в котором я передаю два объекта с одинаковыми именами свойств, и я использую 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 голосов
/ 28 октября 2010

Реализуйте интерфейс 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();
    }
}
...