mardi 8 décembre 2015

Copy a anonymous generic List to an anonymous Array

I need to copy a anonymous generic List<> to an anonymous Array. Fact is that I do not know the Element Type in Design time. All have to be resolved using reflection during run time. Please read my Notes in the Code for further Explanation the Problem. I need a new Approach to get the this working.

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





Aucun commentaire:

Enregistrer un commentaire