2009-05-05 93 views
5

我試圖建立一個對象,它看起來是這樣的:如何反序列化Enumerable.ToList <>()爲List <>

public class MyObject 
    { 
    private IList<AnotherObject> items; 
    public List<AnotherObject> Items 
    { 
     return items.AsEnumerable().ToList<AnotherObject>(); 
    } 
    } 

我使用NHibernate作爲我DAL和有它映射直接到項目字段和所有工作正常。

我也使用Windows工作流和複製器活動不能與通用IList一起使用。 (http://social.msdn.microsoft.com/Forums/en-US/windowsworkflowfoundation/thread/2ca74b60-fd33-4031-be4b-17a79e9afe63)這基本上迫使我使用列表<>包裝,而不是IList <>。這當然會破壞直接的NHibernate映射,因爲NHibernate的IList實現不能直接轉換爲List。

**編輯:Windows工作流需求實際上意味着我將失去對列表的類型安全訪問,無論它如何需要IList。

現在我們的目標是序列化/反序列化這個對象。這適用於二進制序列化,但當我試圖反序列化它們時,底層的NHibernate代理對象會爆炸出現nhibernate錯誤。

所以我嘗試了xml序列化。序列化工作正常,並在序列化的xml文件中給出了我很好的具體類定義,它完全去除了nhibernate代理。但是,當試圖反序列化這個時,我無法將項目添加到列表中,因爲items.AsEnumerable.ToList調用不會讓項目通過.Add方法添加到基礎列表中。

有沒有人對此有任何想法?我是否以這種錯誤的方式去做?

**編輯:NHibernate具體類是NHibernate.Collection.Generic.PersistentGenericBag確實實現IList直接。但是,我失去了通用列表的所有類型安全的好處。這使我不得不爲每個子對象編寫一個包裝器,我真的想盡可能避免這種情況。

回答

2

在選擇是創建你自己的CustomList實現,它是圍繞着實現IList

即一個實例包裝:

public CustomList<AnotherObject> Items  
{  
    return new CustomList<AnotherObject>(items); 
} 

即當您添加到您的CustomList<T>其添加到後臺列表。

這聽起來像只要你的班級實施IList以及IList<T>你會沒事的。

+0

我正在考慮包裝路線,但我並不想爲我的領域模型中的每個子對象編寫包裝。那麼泛型又有什麼意義呢? :)我承認這可能是最後的解決方案。 – 2009-05-05 18:58:26

1

是的,不幸的是,你不能這樣做。調用ToList()會創建一個全新的列表實例,因此當您向該實例添加項目時,它們不會反映到原始列表中(如您已清楚發現的那樣)。

我不使用NHibernate,但我會好奇你的容器是否實現了IList(非通用版本)。從您引用的主題看,System.Collections.IList是實際需要的(並且由List<T>實現,這就是它工作的原因)。你的容器是否實施IList

+1

我不得不爲了適應NHibernate的使用IList的但Windows工作流要求列表。 – 2009-05-05 18:40:53

+0

NHibernate.Collection.Generic.PersistentGenericBag 確實實現了IList。我可以使用它,但是我失去了我不想做的通用列表的類型安全性。另一種方法是按照Alex的建議編寫一個封裝器,但這不是我的理想解決方案。 – 2009-05-05 19:00:12

+1

無論你做什麼,你都會失去型號安全。這就是爲什麼List 沒有實施IList;它要求你打開一個接口,它將在語法上允許你添加一個實際上不匹配泛型類型的元素。你會在序列化的「另一面」訪問這個IList嗎?如果是這樣的話,你將無法將它投回IList 嗎? – 2009-05-05 19:03:29

0

難道你不能像這樣施放它嗎?

public class MyObject 
{ 
    private IList<AnotherObject> items; 
    public List<AnotherObject> Items() 
    { 
     return (List<AnotherObject>)items; 
    } 
} 

沒有嘗試過,但我認爲它應該工作!

0

我覺得NHibernate的PersistentBag(非泛型)集合實現了IList,所以你可以輸入項目爲IList而不是IList<AnotherObject>。你的問題中的鏈接指出,問題是複製器需要一個IList,其中List<T>實現,但IList<T>不(請參閱圖)。

0

它可以投射到IEnumerable <T>?你可以試試這個:

public class MyObject 
{ 
    private IList<AnotherObject> items; 
    public List<AnotherObject> Items 
    { 
     return new List<AnotherObject>items.Cast<AnotherObject>()); 
    } 
    // or, to prevent modifying the list 
    public IEnumerable<AnotherObject> Items 
    { 
     return items.Cast<AnotherObject>(); 
    } 
} 
相關問題