2010-07-04 37 views
7

Tôi đã tạo một lớp có nguồn gốc từ Danh sách. Tuy nhiên khi tôi cố gắng đúc lớp vào đối tượng List khác, tôi gặp lỗi thời gian chạy. Mã của tôi tương tự như mã được đăng bên dưới:Truyền danh sách chung cho một lớp được lấy từ danh sách

public class CategoryObj 
{ 
    public int CategoryID { get; set; } 
    public string CategoryName { get; set; } 
    public string Description { get; set; } 
} 

public class CategoryObjCollection:List<CategoryObj> 
{ 

} 

public void Test() 
{ 
     CategoryObjCollection cat = new CategoryObjCollection(); 
     using (NWDataContext db = new NWDataContext()) 
     { 
      var qry = (from c in db.Categories 
         select new CategoryObj 
         { 
          CategoryID = c.CategoryID, 
          CategoryName = c.CategoryName, 
          Description = c.Description 
         }).ToList(); 
      cat = (CategoryObjCollection)qry; //runtime error Unable to cast object of type 'System.Collections.Generic.List`1[WindowsFormsApplication1.CategoryObj]' to type 'WindowsFormsApplication1.CategoryObjCollection'. 
     } 
} 

Tôi hy vọng ai đó có thể giúp tôi về điều này. Cảm ơn.

Trả lời

6

thử này

public class CategoryObjCollection:List<CategoryObj> 
{ 
    public CategoryObjCollection(IEnumerable<CategoryObj> items) : base(items){} 
} 


cat = new CategoryObjCollection(qry); 
12

Tại sao bạn mong chờ để có thể đúc? Đối tượng không phải là một phiên bản của CategoryObjCollection. Điểm của các kiểu tham chiếu (khi chúng thực sự được đúc thay vì gọi các chuyển đổi rõ ràng) là nói với trình biên dịch rằng bạn tin rằng thời gian thực hiện của đối tượng thực sự tương thích với loại bạn chỉ định, để bạn có thể sử dụng thành viên của loại cụ thể đó (sau khi thực hiện kiểm tra thời gian). Trong trường hợp này, phương thức mở rộng ToList chỉ tạo một List<T> mới.

Thêm vào điểm này, loại CategoryObjCollection của bạn có ý nghĩa gì để đạt được ngay từ đầu? Nếu nó có bất kỳ trạng thái nào khác ngoài danh sách bình thường, bạn sẽ mong đợi trạng thái đó đến từ đâu sau truy vấn LINQ của bạn? Nếu nó không có bất kỳ trạng thái nào khác, nó có thực sự thêm bất kỳ lợi ích nào không? Có lẽ loại của bạn thực sự phải là chứa một danh sách thay vì xuất phát từ nó? Sau đó, bạn có thể tạo một thể hiện mới của loại bằng cách sử dụng kết quả của truy vấn.

Nói chung, đó thường là mùi thiết kế để lấy được từ List<T>. Nó không cung cấp nhiều cách để chuyên "listiness" của nó (không giống như, nói, Collection<T>). Nó thường là một dấu hiệu cho thấy bạn nên suy nghĩ về sáng tác thay vì thừa kế.

+0

Có vẻ như tôi đang cố gắng làm một C++ - giống như bí danh typedef. –

+0

@Jaroslav: Rất có thể - nhưng đó không phải là những gì thừa kế, và nó không phải là những gì nó nên được sử dụng cho. –

+0

Thật vậy. Đó là những gì 'chỉ thị' sử dụng cho. –

3

Dàn diễn viên sẽ chỉ hoạt động nếu bạn đã triển khai toán tử chuyển đổi. Nhưng nó không phải là một cách tiếp cận rất hiệu quả.

Bạn đang cố gắng tạo bí danh loại (như trong C++ typedef)?

using CategoryObjCollection = System.Collections.Generic.List<myNamespace.CategoryObj>; 

Bây giờ bạn có thể tự do chuyển đổi giữa CategoryObjCollectionList<CategoryObj> (mà là cùng loại - chỉ đặt tên khác nhau

tôi sẽ cũng sử dụng một phương pháp khác nhau để điền vào danh sách lên:.

db.Categories.ForEach(c => 
    cat.Add(new CategoryObj() 
     { 
      CategoryID = c.CategoryID, 
      CategoryName = c.CategoryName, 
      Description = c.Description 
     })); 
0

Tại sao bạn đang truyền? Bạn thực sự không nên truyền .... chỉ cần thêm vòng lặp qua qry và điền vào danh sách cat của bạn lên.

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