2009-05-05 29 views
5

Tôi đang cố gắng để xây dựng một đối tượng mà trông giống như sau:Làm thế nào để deserialize Enumerable.ToList <>() List <>

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

Tôi đang sử dụng NHibernate là Dal của tôi và có nó lập bản đồ trực tiếp vào trường mục và tất cả đều hoạt động tốt.

Tôi cũng đang sử dụng Windows Workflow và hoạt động sao chép không hoạt động với IList chung chung. (http://social.msdn.microsoft.com/Forums/en-US/windowsworkflowfoundation/thread/2ca74b60-fd33-4031-be4b-17a79e9afe63) Điều này về cơ bản là buộc tôi phải sử dụng danh sách gói <> thay vì IList <>. Điều này tất nhiên phá vỡ ánh xạ NHibernate trực tiếp như thực hiện IList NHibernate không thể được đúc trực tiếp vào một danh sách.

** CHỈNH SỬA: Yêu cầu quy trình làm việc của Windows thực sự có nghĩa là tôi sẽ mất quyền truy cập an toàn loại vào danh sách bất kể nó yêu cầu IList như thế nào.

Bây giờ, mục tiêu là sắp đặt từng hàng/deserialize đối tượng này. Điều này làm việc tốt với serialization nhị phân nhưng các đối tượng proxy NHibernate bên dưới phát nổ với lỗi nhibernate khi tôi cố gắng deserialize chúng.

Vì vậy, tôi đã thử xml serialization. Các serialization hoạt động tốt và mang lại cho tôi định nghĩa lớp bê tông đẹp của tôi trong xml serialized tập tin mà dải ra các nhibernate proxy hoàn toàn. Tuy nhiên, khi cố gắng deserialize này, tôi không thể thêm các mục vào danh sách như các cuộc gọi items.AsEnumerable.ToList sẽ không cho phép các mục được thêm vào danh sách cơ bản thông qua phương thức .Add.

Có ai có bất kỳ suy nghĩ nào về điều này không? Tôi đang đi về điều này một cách sai lầm?

** CHỈNH SỬA: Lớp bê tông NHibernate là NHibernate.Collection.Generic.PersistentGenericBag thực sự thực thi trực tiếp IList. Tuy nhiên, tôi đã mất tất cả các lợi ích loại an toàn của danh sách chung. Điều này đặt tôi trở lại trong lĩnh vực phải viết một wrapper cho mỗi đối tượng trẻ em và tôi thực sự muốn tránh điều đó nếu có thể.

Trả lời

2

On lựa chọn là để tạo ra thực hiện CustomList của riêng bạn mà là bao bọc xung quanh một trường hợp mà thực hiện IList

tức là:

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

ví dụ: khi bạn thêm vào CustomList<T> của bạn nó sẽ thêm vào danh sách ủng hộ.

Có vẻ như miễn là lớp học của bạn triển khai IList cũng như IList<T> bạn sẽ ổn.

+0

Tôi đang dự tính lộ trình bao bọc nhưng tôi không thực sự muốn viết trình bao bọc cho từng đối tượng con trong mô hình miền của mình. Thế nào là điểm của generics? :) Tôi sẽ thừa nhận đây có lẽ là một giải pháp cuối cùng mặc dù. –

+0

Giải pháp hiện tại tôi đang làm việc với một lớp bao bọc thực hiện cả IList và IList . Các phương pháp không chung chung đã được viết để thực hiện kiểm tra kiểu. Nhưng về cơ bản nó chỉ kết thúc một IList nội bộ. –

1

Có, rất tiếc, bạn không thể thực hiện theo cách này. Gọi ToList() sẽ tạo ra một phiên bản mới của danh sách, vì vậy khi bạn thêm các mục vào trường hợp đó, chúng sẽ không được phản ánh trong danh sách gốc (như bạn đã khám phá rõ ràng).

Tôi không sử dụng NHibernate, nhưng tôi sẽ tò mò muốn xem liệu vùng chứa của bạn có triển khai IList (phiên bản không phải là chung chung) hay không. Từ chuỗi bạn tham chiếu, có vẻ như System.Collections.IList là những gì thực sự cần thiết (và được thực hiện bởi List<T>, đó là lý do tại sao nó hoạt động). Vùng chứa của bạn có triển khai IList không?

+1

tôi phải sử dụng IList để thích ứng NHibernate nhưng Windows Workflow đòi hỏi Danh sách . –

+0

NHibernate.Collection.Generic.PersistentGenericBag thực sự thực hiện IList. Tôi có thể sử dụng điều này nhưng sau đó tôi bị mất loại an toàn của danh sách chung mà tôi không muốn làm. Cách khác là viết một wrapper theo gợi ý của Alex bên dưới, nhưng nó không phải là giải pháp lý tưởng của tôi. –

+1

Không có vấn đề gì bạn làm bạn sẽ mất an toàn loại. Đây là lý do tại sao Danh sách không triển khai IList; nó yêu cầu bạn mở một giao diện sẽ cho phép bạn thêm một phần tử không thực sự khớp với kiểu của generic. Bạn sẽ được truy cập vào IList này trên "phía bên kia" của serialization? Bạn sẽ không thể chuyển nó trở lại một số IL2 nếu đó là trường hợp? –

0

Bạn không thể truyền nó như thế này?

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

Rất tiếc, bạn có thể thử nó, nhưng tôi nghĩ nó nên hoạt động!

+1

Điều này không hoạt động vì đối tượng bên dưới trong IList là NHibernate.Collection.Generic.PersistentGenericBag không trực tiếp có thể chuyển sang Danh sách

+0

Ah, ok, sau đó không bao giờ nhớ câu trả lời của tôi: S – fredrik

0

Tôi nghĩ bộ sưu tập NHibernate PersistentBag (không chung) thực hiện IList để bạn có thể nhập các mục là IList thay vì IList<AnotherObject>. Liên kết trong câu hỏi của bạn nói rằng vấn đề là bản sao yêu cầu một IList mà List<T> thực hiện nhưng IList<T> không (đi hình).

+0

Xem nhận xét của Adam ở trên tại sao IList không thực hiện IList. Tôi đã không nghĩ về nó trước khi bản thân mình. –

0

Nó có thể được truyền tới IEnumerable <T>? Bạn có thể thử này:

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>(); 
    } 
} 
+0

Tôi cần một IList cho Windows Workflow. –

Các vấn đề liên quan