我在 List<T>里获得了一个匿名类型的实例。
var anBook=new []{
new {Code=10, Book ="Harry Potter"},
new {Code=11, Book="James Bond"}
};
以下是 clearBook 定义,是否可能将其转换为 List:
public class ClearBook
{
int Code;
string Book;
}
通过直接转换,即不通过循环遍历anBook,您可以实现什么?我在 List<T>里获得了一个匿名类型的实例。
var anBook=new []{
new {Code=10, Book ="Harry Potter"},
new {Code=11, Book="James Bond"}
};
以下是 clearBook 定义,是否可能将其转换为 List:
public class ClearBook
{
int Code;
string Book;
}
通过直接转换,即不通过循环遍历anBook,您可以实现什么?好的,您可以使用:
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
编译和缓存策略),但这可能不值得。
如Marc所说,可以使用反射和表达式树来完成... 幸运的是,在MiscUtil中有一个类恰好可以做到这一点。但是,仔细查看您的问题后,似乎您想要将此转换应用于集合(数组、列表或其他)而不使用循环,这是不可能的。您正在从一种类型转换为另一种类型 - 没有像引用ClearBook一样使用匿名类型的引用。
然而,为了说明PropertyCopy类的工作原理,您只需要:
var books = anBook.Select(book => PropertyCopy<ClearBook>.CopyFrom(book))
.ToList();
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);
(否则你试图在 obj
上使用 tmp
的 getter,这是行不通的) - Philip Atz最简单的方法可能就是使用某种类型的序列化方法。
类似于以下这些内容
class ClearBook
{
public int Code { get; set; }
public string Book { get; set; }
}
ClearBook[] newList = JsonSerializer.Deserialize<ClearBook[]>(JsonSerializer.Serialize(anBook));