简体   繁体   English

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

[英]How to use reflection on a property of type ICollection?

I have a method where I am passing in two object, which have the same property names, and I'm using Reflection to get the values from one object and set the values on the other. 我有一个方法,我传入两个具有相同属性名称的对象,并使用反射从一个对象获取值,并在另一个对象上设置值。 My problem is when I come across a property that is a collection, the original is EntityCollection and the one getting set is ObservableCollection, and I'm obviously going to throw a casting error when I try to set the value. 我的问题是,当我遇到一个属性是一个集合时,原始属性是EntityCollection,而一个被设置的属性是ObservableCollection,当我尝试设置该值时,显然会抛出强制转换错误。

So how would I go about this? 那么我将如何处理呢? I thought one way would be to get the instance of the EntityCollection property and in a loop use Activator.CreateInstance() to add a new item to the ObservableCollection. 我认为一种方法是获取EntityCollection属性的实例,然后在循环中使用Activator.CreateInstance()向ObservableCollection添加新项。 But I come across another question of how to get the original instance. 但是我遇到了另一个有关如何获取原始实例的问题。

I would be greatly appreciative for some insight into this dilemma. 对于这一困境的一些见解,我将不胜感激。 I'll post the code for the method that I'm working with. 我将发布正在使用的方法的代码。 It currently doesn't work, mainly I posted it just for a reference. 它目前不起作用,主要是我将其发布只是为了参考。 So please don't point out the obvious. 因此,请不要指出显而易见的内容。 Thanks in advance. 提前致谢。

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);
        }
    }
}

Implement the ICloneable interface to provide a deep copy. 实现ICloneable接口以提供深层副本。 You should be able to find some examples, but here is a starting point: 您应该可以找到一些示例,但这是一个起点:

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

http://en.csharp-online.net/ICloneable 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();
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM