deccks
deccks

Reputation: 67

Convert generic object list to non-generic type list

I am trying to convert a List of System.Object objects to a List of strongly typed objects.

Here is the error I am getting:

Object of type 'System.Collections.Generic.List`1[System.Object]' cannot be converted to type 'System.Collections.Generic.List`1[TestApp.Tsc_Mrc_Step]'.

The purpose is because I am writing a business data layer for my project that all you have to do is name your class and properties the same name as entities in your database and the data layer will automatically populate referenced tables as types that are declared in the class.

The business data layer uses reflection, generics and objects to deal with all of this.

Below is the code I tried to put a List of objects into a List of known types. The thing is, the object is the known type but I pass it as an object....How do I convert it to the known type without knowing what it is?

            bool isCoollection = false;
            Type t = GetTypeInsideOfObjectByTypeName(o, tableName, out isCoollection);

            List<object> objectColl = new List<object>();

            object obj = Activator.CreateInstance(t);
            if (obj != null)
            {
                PropertyInfo[] objectProps = obj.GetType().GetProperties();
                foreach (PropertyInfo op in objectProps)
                {
                    if (HasColumn(reader, op.Name))
                    {
                        op.SetValue(obj, reader[op.Name]);
                    }
                }

                if (isCoollection)
                {
                    objectColl.Add(obj);
                }
            }

            if (isCoollection)
            {
                IEnumerable<object> objs = objectColl.AsEnumerable();

                SetObject(o, objs);
            }
            else
            {
                SetObject(o, obj);
            }

Here is SetObject:

            public static void SetObject(object parentObject, object newObject)
            {
                PropertyInfo[] props = parentObject.GetType().GetProperties();
                string typeName = newObject.GetType().Name;
                foreach (PropertyInfo pi in props)
                {
                    if (pi.PropertyType.Name.ToLower() == typeName.ToLower())
                    {
                        pi.SetValue(parentObject, newObject);
                    }
                    else if (!pi.PropertyType.IsValueType && !pi.PropertyType.Namespace.ToLower().Contains("system"))
                    {
                        SetObject(pi.GetValue(parentObject), newObject);
                    }
                }
            }

Upvotes: 1

Views: 4993

Answers (2)

deccks
deccks

Reputation: 67

Ok, I accomplished my goal. All thanks to the dynamic variable. I am impressed that I am able to do that using .NET. What do you think? Thanks :)

Type t = GetTypeInsideOfObjectByTypeName(o, tableName, out isCoollection);

Type genericListType = typeof(List<>).MakeGenericType(t);

object coll = Activator.CreateInstance(genericListType);

dynamic objectColl = Convert.ChangeType(coll, coll.GetType());

dynamic d = Convert.ChangeType(obj, obj.GetType());

objectColl.Add(d);

Upvotes: 2

Kyle W
Kyle W

Reputation: 3752

If you know all of the values are of the required type in a list:

List<Object> objects;
List<Cat> cats = objects.Cast<Cat>().ToList();

If not all the values are of the type, and you want to weed out the ones that aren't:

List<Object> objects;
List<Cat> cats = objects.OfType<Cat>().ToList();

Both require LINQ.

If you don't know the type until runtime, you have to use reflection.

How to call a generic method through reflection

Upvotes: 5

Related Questions