2009-01-15 15 views
21

Tengo un tipo anónimo dentro de una lista anBook:Convertir Anónimo Tipo de Clase

var anBook=new []{ 

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

consiste en posible convertir a una lista con la siguiente definición de clearBook:

public class ClearBook 
{ 
    int Code; 
    string Book; 
} 

mediante el uso de conversión directa, es decir, sin bucle a través de un libro?

Respuesta

37

Bueno, que puede usar:

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

pero no, no hay apoyo de conversión directa. Obviamente, usted tendrá que añadir descriptores de acceso, etc. (no cometer los campos públicos) - supongo:

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

Por supuesto, la otra opción es comenzar con los datos de cómo quiere que:

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

también hay cosas que podría hacer para correlacionar los datos con la reflexión (tal vez usando un Expression para recopilar y almacenar en caché la estrategia), pero probablemente no vale la pena.

11

Como dice Marc, se puede hacer con árboles de reflexión y expresión ... y por suerte, hay una clase en MiscUtil que hace exactamente eso. Sin embargo, al ver su pregunta más de cerca, parece que desea aplicar esta conversión a una colección (matriz, lista o lo que sea) sin bucles. Eso no puede funcionar. Está convirtiendo de un tipo a otro; no es como si pudiera usar una referencia al tipo anónimo como si fuera una referencia a ClearBook.

Para dar un ejemplo de cómo funciona la clase PropertyCopy embargo, usted sólo necesita:

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

¿No puede el CLR inferir el tipo y el nombre de la propiedad y hacer la conversión automática? .Net 4.0 debería mejorar esto – Graviton

+0

Para que yo no tenga que declarar el tipo yo mismo. – Graviton

+0

No puedo decir que haya visto mucha demanda por esto, y si se siente como una mala idea en general. –

4

¿Qué hay de éstos extensión? simple llame al .ToNonAnonymousList en su tipo anónimo ...

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; 
    } 
Cuestiones relacionadas