У меня есть анонимный тип внутри List anBook:
var anBook=new []{
new {Code=10, Book = "Harry Potter"},
new {Code=11, Book = "James Bond"}
};
Можно ли преобразовать его в список со следующим определением clearBook:
public class ClearBook
{
int Code;
string Book;
}
с помощью прямого преобразования, то есть без циклического просмотра книги?





Что ж, вы можете использовать:
var list = anBook.Select(x => new ClearBook {
Code = x.Code, Book = x.Book}).ToList();
но нет, поддержки прямого преобразования нет. Очевидно, вам нужно будет добавить аксессоры и т. д. (Не делайте поля общедоступными) - я бы предположил:
public int Code { get; set; }
public string Book { get; set; }
Конечно, другой вариант - начать с данных так, как вы хотите:
var list = new List<ClearBook> {
new ClearBook { Code=10, Book = "Harry Potter" },
new ClearBook { Code=11, Book = "James Bond" }
};
Есть также вещи, которые вы можете сделать для сопоставления данных с отражением (возможно, используя Expression для компиляции и кеширования стратегии), но, вероятно, это того не стоит.
Как говорит Марк, это можно сделать с помощью деревьев отражений и выражений ... и, как назло, в MiscUtil есть класс, который делает именно это. Однако, если взглянуть на ваш вопрос более внимательно, похоже, что вы хотите применить это преобразование к коллекции (массив, список или что-то еще) без зацикливания. Это не может сработать. Вы конвертируете из одного типа в другой - это не значит, что вы можете использовать ссылку на анонимный тип, как если бы это ссылка на ClearBook.
Чтобы дать пример того, как работает класс PropertyCopy, вам просто нужно:
var books = anBook.Select(book => PropertyCopy<ClearBook>.CopyFrom(book))
.ToList();
Так что мне не нужно самому объявлять тип.
Я не могу сказать, что видел на это большой спрос, и в целом это кажется плохой идеей.
Использование его для интеграционных тестов на JsonResult из контроллера MVC
А что насчет этого расширения? просто вызовите .ToNonAnonymousList вашего анонимного типа ..
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;
}
В вашем ToType<T>() вам нужно сделать: var value = GetProperty(obj.GetType(), pi.Name).GetValue(obj, null); и GetProperty(typeof(T), pi.Name).SetValue(tmp, value, null); (в противном случае вы пытаетесь использовать получатель tmp на obj, что не сработает)
Самый простой способ сделать это - использовать какой-нибудь метод сериализации.
что-то вроде этого
class ClearBook
{
public int Code { get; set; }
public string Book { get; set; }
}
ClearBook[] newList = JsonSerializer.Deserialize<ClearBook[]>(JsonSerializer.Serialize(anBook));
А где здесь List <ClearBook>?
Не может CLR определить тип и имя свойства и выполнить автоматическое преобразование? .Net 4.0 должен улучшить это