C# 将匿名类型转换为类

C# 将匿名类型转换为类,c#,linq,anonymous-types,C#,Linq,Anonymous Types,我在一本书的列表中找到了一个匿名类型: var anBook=new []{ new {Code=10, Book ="Harry Potter"}, new {Code=11, Book="James Bond"} }; 可以将其转换为具有以下clearBook定义的列表: public class ClearBook { int Code; string Book; } 通过使用直接转换,即不通过anBook循环 嗯,你可以使用: var list = anBook.Sele

我在一本书的列表中找到了一个匿名类型:

var anBook=new []{

new {Code=10, Book ="Harry Potter"},
new {Code=11, Book="James Bond"}
};
可以将其转换为具有以下clearBook定义的列表:

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" }
};
var list=新列表{
新的ClearBook{Code=10,Book=“Harry Potter”},
新的ClearBook{Code=11,Book=“James Bond”}
};

您还可以使用反射来映射数据(可能使用
表达式来编译和缓存策略),但这可能不值得。

正如Marc所说,可以使用反射和表达式树来完成。。。幸运的是,有一门课就是这么做的。但是,更仔细地看一下您的问题,您似乎希望在不循环的情况下将此转换应用于集合(数组、列表等)。那不可能。您正在从一种类型转换到另一种类型-这不像您可以像引用ClearBook一样使用对匿名类型的引用

要给出PropertyCopy类如何工作的示例,您只需要:

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

这些扩展如何?只需在匿名类型上调用.tononanymousList即可

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;
    }
公共静态对象ToNonAnonymousList(此列表,类型t)
{
//定义表示T类型对象列表的系统类型:
Type genericType=typeof(列表)。MakeGenericType(t);
//创建定义类型的对象实例:
对象l=Activator.CreateInstance(genericType);
//从列表中获取方法Add:
MethodInfo addMethod=l.GetType().GetMethod(“添加”);
//在调用列表中循环:
foreach(列表中的T项)
{
//通过调用扩展名ToType()将列表中的每个对象转换为T对象
//将此对象添加到新创建的列表:
Invoke(l,new[]{item.ToType(t)});
}
//返回T对象的列表:
返回l;
}
公共静态对象ToType(此对象obj,T类型)
{
//创建T类型对象的实例:
对象tmp=Activator.CreateInstance(Type.GetType(Type.ToString());
//循环遍历要转换的对象的属性:
foreach(obj.GetType().GetProperties()中的PropertyInfo pi)
{
尝试
{
//获取属性值并尝试将其分配给T类型对象的属性:
tmp.GetType().GetProperty(pi.Name).SetValue(tmp,pi.GetValue(obj,null),null);
}
捕获(例外情况除外)
{
Logging.Log.Error(ex);
}
}
//返回T类型对象:
返回tmp;
}

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

大概是这样的

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

ClearBook[] newList = JsonSerializer.Deserialize<ClearBook[]>(JsonSerializer.Serialize(anBook));
类ClearBook
{
公共整数代码{get;set;}
公共字符串书{get;set;}
}
ClearBook[]newList=JsonSerializer.Deserialize(JsonSerializer.Serialize(anBook));

CLR不能推断类型和属性名称并进行自动转换吗。Net 4.0应该在这方面有所改进,这样我就不必自己声明类型了。我不能说我看到了对它的大量需求,而且通常感觉这是个坏主意。使用它对来自MVC控制器的JsonResult进行集成测试,这里的列表在哪里?在
ToType()
中,您需要执行:
var value=GetProperty(obj.GetType()),pi.Name).GetValue(obj,null)
GetProperty(typeof(T),pi.Name).SetValue(tmp,value,null)
(否则您试图在
obj
上使用
tmp
的getter,这将不起作用)