Domanda

Ho un tipo anonimo all'interno di un Elenco anBook:

var anBook=new []{

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

È possibile convertirlo in un Elenco con la seguente definizione di clearBook:

public class ClearBook
{
  int Code;
  string Book; 
}

utilizzando la conversione diretta, ovvero senza scorrere un anBook?

È stato utile?

Soluzione

Bene, puoi usare:

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

ma no, non esiste supporto per la conversione diretta. Ovviamente dovrai aggiungere accessori, ecc. (Non rendere pubblici i campi) - Immagino:

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

Ovviamente, l'altra opzione è iniziare con i dati come lo desideri:

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

Ci sono anche cose che potresti fare per mappare i dati con reflection (forse usando un Expression per compilare e memorizzare nella cache la strategia), ma probabilmente non ne vale la pena.

Altri suggerimenti

Come dice Marc, può essere fatto con alberi di riflessione ed espressione ... e per fortuna, c'è una classe in MiscUtil che fa esattamente questo. Tuttavia, esaminando la tua domanda più da vicino sembra che tu voglia applicare questa conversione a una raccolta (array, elenco o altro) senza loop . Questo non può funzionare. Stai convertendo da un tipo a un altro - non è che puoi usare un riferimento al tipo anonimo come se fosse un riferimento a ClearBook.

Per dare un esempio di come funziona la classe PropertyCopy, devi solo:

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

E queste estensioni? chiama semplicemente .ToNonAnonymousList sul tuo tipo anonimo ..

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;
    }
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top