Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Convert array of any type to List<T> (C#)

Tags:

c#

The function below accepts an object, which can sometimes be an array of a given type. In this case, I suppose the type could be determined with obj[0].GetType(), assuming the array has at least one member. I would like to convert such an array to a generic List<T> of appropriate type, but the code below only succeeds in converting to List<object>. How can this be done?

        public object GetDeserializedObject(object obj, Type targetType)
        {
            if (obj is Array)
            {
                List<object> obj2 = new List<object>();
                for (int i = 0; i < ((Array)obj).Length; i++)
                {
                    obj2.Add(((object[])obj)[i]);
                }
                obj = obj2;
            }
            return obj;
        }

Note that GetSerializedObject() implements a function belonging to the IDataContractSurrogate interface, so I don't think I can change its signature as shown.

like image 604
nw. Avatar asked Dec 16 '09 20:12

nw.


2 Answers

Assuming you don't know the type at compile-time, you'll want to create a generic method to do it, and then call it by reflection. For example:

private static List<T> ConvertArray<T>(Array input)
{
    return input.Cast<T>().ToList(); // Using LINQ for simplicity
}

public static object GetDeserializedObject(object obj, Type targetType)
{
    if (obj is Array)
    {
        MethodInfo convertMethod = typeof(...).GetMethod("ConvertArray",
            BindingFlags.NonPublic | BindingFlags.Static);
        MethodInfo generic = convertMethod.MakeGenericMethod(new[] {targetType});
        return generic.Invoke(null, new object[] { obj });
    }
    return obj;
}

(If you do know the type at compile-time, just make it a generic method and call Cast and ToList directly.)

like image 131
Jon Skeet Avatar answered Oct 16 '22 14:10

Jon Skeet


Try the Cast() Linq method:

    public object GetDeserializedObject<T>(object obj)
    {
        if (obj is Array)
        {
            var list = ((Array)obj).Cast<T>().ToList();
            obj = list;
        }
        return obj;
    }

And you'll specify the type you want in T.

like image 37
Matthew Groves Avatar answered Oct 16 '22 12:10

Matthew Groves