如何在 ICollection 类型的属性上使用反射?
我有一种方法,其中传递两个对象,它们具有相同的属性名称,并且我使用反射从一个对象获取值并在另一个对象上设置值。我的问题是,当我遇到一个集合属性时,原始属性是 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);
}
}
}
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.
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. 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);
}
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
实现ICloneable接口以提供深拷贝。您应该能够找到一些示例,但这是一个起点:
http://msdn.microsoft.com/en-us/library/system.icloneable%28v=VS.71%29.aspx
http://en.csharp-online.net/ICloneable
Implement the ICloneable interface to provide a deep copy. 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://en.csharp-online.net/ICloneable