2009-01-15 187 views
21

我有一個列表anBook內部的匿名類型:轉換匿名類型來

var anBook=new []{ 

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

是儘可能將其與clearBook的如下定義轉換到一個列表:使用

public class ClearBook 
{ 
    int Code; 
    string Book; 
} 

直接轉換,即沒有循環通過一本書?

回答

37

嗯,你可以使用:

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編譯和緩存策略),但它可能是不值得的。

11

正如馬克所說,它可以通過反射和表達樹來完成...並且幸運的是,MiscUtil中有一個類就是這樣做的。但是,更仔細地看看你的問題,聽起來像你想要將這個轉換應用到一個集合(數組,列表或其他)而沒有循環。這不可能工作。您正在從一種類型轉換爲另一種類型 - 它不像您可以使用對匿名類型的引用,就好像它是對ClearBook的引用。

舉的PropertyCopy類的工作雖然一個例子,你只需要:

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

不能CLR推斷類型和屬性名稱並執行自動轉換嗎? .Net 4.0應該改進這個 – Graviton 2009-01-15 09:03:04

4

什麼有關這些擴展?簡單地調用您的匿名類型的.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; 
    }