【发布时间】:2015-12-08 13:32:28
【问题描述】:
我需要将一个匿名通用 List 复制到一个匿名数组。 事实是我不知道设计时的元素类型。所有都必须在运行时使用反射来解决。 请阅读我在代码中的注释以进一步解释问题。 我需要一种新的方法来让它发挥作用。
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
namespace MapperTestLogic
{
public class temp
{
//Source is an Object with Properties of Generic Lists, Destination is an Object with Properties of type Array
//The Property Names are allways the same
public void Copy(object Source, object Destination)
{
Type sourceType = Source.GetType();
Type destinationType = Destination.GetType();
foreach (PropertyInfo sourceProp in sourceType.GetProperties())
{
if (sourceProp.GetValue(Source, null) != null)
{
PropertyInfo destProp = destinationType.GetProperty(sourceProp.Name); //Get the same Property in destination
Type sourceItemType;
Type destItemType;
//Destination is Array, Source inherits from IList..
if (destProp != null && destProp.PropertyType.IsArray && InheritsFromIList(sourceProp, out sourceItemType))
{
//..get the Source
var colSource = ((IEnumerable<dynamic>)sourceProp.GetValue(Source, null)).ToList();
var colDestination = destProp.GetValue(Destination, null);
//..get the Destination Element Type (They are not the same Types as in the List but they have the same name)
Type t = colDestination.GetType();
destItemType = t.GetElementType();
var listType = typeof(List<>);
var constructedListType = listType.MakeGenericType(destItemType);
var listInstance = (IList)Activator.CreateInstance(constructedListType); //Create a new IList-Instance of destination Element Type
foreach (var sourceItem in colSource)
{
//Iterate through sourcitems and create instances of destination type
var di = Activator.CreateInstanceFrom(destItemType.Assembly.CodeBase, destItemType.FullName);
var destItem = di.Unwrap();
di = null;
listInstance.Add(destItem);
}
//Create new Array Instance with the the correct Destination Elementtype in the correct Size..
var arrDestination = Activator.CreateInstance(t, new object[] { listInstance.Count });
//From here on the Code is not working properly
foreach(var item in listInstance)
{
arrDestination[0] = item; //Here I will copy the value but get the compiler Error: Cannot apply indexing with [] to an expression of type object
}
//I know why etc. I need now an other approach to solve my problem.
destProp.SetValue(Destination, arrDestination);
}
}
}
}
private bool InheritsFromIList(PropertyInfo sourceProp, out Type ItemType)
{
ItemType = typeof(NullClass);
foreach (Type interfaceType in sourceProp.PropertyType.GetInterfaces())
{
if (interfaceType.IsGenericType && interfaceType.GetGenericTypeDefinition() == typeof(IList<>))
{
//if so, work each element of the List
ItemType = sourceProp.PropertyType.GetGenericArguments()[0];
break;
}
}
if (ItemType != typeof(NullClass))
{
return true;
}
else
{
return false;
}
}
}
internal class NullClass
{
//Helperclass for Method InheritsFromIList
}
}
【问题讨论】:
-
..你知道
.ToArray()吗?即使元素类型是匿名类型,它也可以工作。 -
.ToArra() 不适用于 IList。它仅适用于 List 因为无法使用 Activator 创建匿名类型的 List 我只能实现 IList var listInstance = (IList)Activator.CreateInstance(constructedListType);
-
这里的最终目标是什么 - 因为你不能声明一个匿名类型的数组,客户端将如何使用结果?
-
它将填满目标对象
标签: c# arrays generics reflection anonymous