Question

I got an anonymous type inside a List anBook:

var anBook=new []{

new {Code=10, Book ="Harry Potter"},
new {Code=11, Book="James Bond"}
};

Is to possible to convert it to a List with the following definition of clearBook:

public class ClearBook
{
  int Code;
  string Book; 
}

by using direct conversion, i.e., without looping through anBook?

Was it helpful?

Solution

Well, you could use:

var list = anBook.Select(x => new ClearBook {
               Code = x.Code, Book = x.Book}).ToList();

but no, there is no direct conversion support. Obviously you'll need to add accessors, etc. (don't make the fields public) - I'd guess:

public int Code { get; set; }
public string Book { get; set; }

Of course, the other option is to start with the data how you want it:

var list = new List<ClearBook> {
    new ClearBook { Code=10, Book="Harry Potter" },
    new ClearBook { Code=11, Book="James Bond" }
};

There are also things you could do to map the data with reflection (perhaps using an Expression to compile and cache the strategy), but it probably isn't worth it.

OTHER TIPS

As Marc says, it can be done with reflection and expression trees... and as luck would have it, there's a class in MiscUtil which does exactly that. However, looking at your question more closely it sounds like you want to apply this conversion to a collection (array, list or whatever) without looping. That can't possibly work. You're converting from one type to another - it's not like you can use a reference to the anonymous type as if it's a reference to ClearBook.

To give an example of how the PropertyCopy class works though, you'd just need:

var books = anBook.Select(book => PropertyCopy<ClearBook>.CopyFrom(book))
                                 .ToList();

What about these extension? simple call the .ToNonAnonymousList on your anonymous type..

public static object ToNonAnonymousList<T>(this List<T> list, Type t)
    {
        //define system Type representing List of objects of T type:
        Type genericType = typeof (List<>).MakeGenericType(t);

        //create an object instance of defined type:
        object l = Activator.CreateInstance(genericType);

        //get method Add from from the list:
        MethodInfo addMethod = l.GetType().GetMethod("Add");

        //loop through the calling list:
        foreach (T item in list)
        {
            //convert each object of the list into T object by calling extension ToType<T>()
            //Add this object to newly created list:
            addMethod.Invoke(l, new[] {item.ToType(t)});
        }
        //return List of T objects:
        return l;
    }
    public static object ToType<T>(this object obj, T type)
    {
        //create instance of T type object:
        object tmp = Activator.CreateInstance(Type.GetType(type.ToString()));

        //loop through the properties of the object you want to covert:          
        foreach (PropertyInfo pi in obj.GetType().GetProperties())
        {
            try
            {
                //get the value of property and try to assign it to the property of T type object:
                tmp.GetType().GetProperty(pi.Name).SetValue(tmp, pi.GetValue(obj, null), null);
            }
            catch (Exception ex)
            {
                Logging.Log.Error(ex);
            }
        }
        //return the T type object:         
        return tmp;
    }
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top