27

我在 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; 
}

通过使用直接转换,即不循环通过 anBook?

4

4 回答 4

50

好吧,你可以使用:

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" }
};

您还可以做一些事情来使用反射映射数据(也许使用 anExpression来编译和缓存策略),但这可能不值得。

于 2009-01-15T08:27:11.807 回答
11

正如 Marc 所说,它可以通过反射和表达式树来完成……幸运的是,MiscUtil中有一个类可以做到这一点。但是,更仔细地查看您的问题,听起来您想将此转换应用于集合(数组、列表或其他)而不使用循环。那是不可能的。您正在从一种类型转换为另一种类型 - 这不像您可以使用对匿名类型的引用,就好像它是对 ClearBook 的引用一样。

不过,要举例说明 PropertyCopy 类的工作原理,您只需要:

var books = anBook.Select(book => PropertyCopy<ClearBook>.CopyFrom(book))
                                 .ToList();
于 2009-01-15T08:41:42.560 回答
8

这些扩展呢?简单地在你的匿名类型上调用 .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;
    }
于 2010-12-31T13:39:07.340 回答
0

最简单的方法可能是使用某种类型的序列化方法。

像这样的东西

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

ClearBook[] newList = JsonSerializer.Deserialize<ClearBook[]>(JsonSerializer.Serialize(anBook));
于 2021-01-17T20:32:27.873 回答