2009-04-08 38 views
10

Cách tốt nhất để chuyển đổi một bộ sưu tập phi chung chung thành một bộ sưu tập chung là gì? Có cách nào để LINQ nó?Cách tốt nhất để chuyển đổi một bộ sưu tập phi chung chung thành bộ sưu tập chung

Tôi có mã sau đây.

public class NonGenericCollection:CollectionBase 
{ 
    public void Add(TestClass a) 
    { 
     List.Add(a); 
    } 
} 

public class ConvertTest 
{ 
    public static List<TestClass> ConvertToGenericClass(NonGenericCollection collection) 
    { 
     // Ask for help here. 
    } 
} 

Cảm ơn!

Trả lời

22

Vì bạn có thể đảm bảo họ đang tất cả các trường TestClass, sử dụng LINQ Cast<T> method:

public static List<TestClass> ConvertToGenericClass(NonGenericCollection collection) 
{ 
    return collection.Cast<TestClass>().ToList(); 
} 

Edit: Và nếu bạn chỉ muốn các trường hợp TestClass của một (có thể) bộ sưu tập đồng nhất, lọc nó với OfType <T>:

public static List<TestClass> ConvertToGenericClass(NonGenericCollection collection) 
{ 
    return collection.OfType<TestClass>().ToList(); 
} 
+1

Tôi không nghĩ bạn cần Cast () sau OfType (), nhưng tôi có thể bị nhầm lẫn. – Samuel

+0

@Samuel - Bạn nói đúng. OfType () sẽ trả về IEnumerable , vì vậy đó là tất cả những gì bạn cần. Đã chỉnh sửa và sửa. –

1

Có thể không phải cách tốt nhất, nhưng nó sẽ hoạt động.

public class ConvertTest 
{ 
    public static List<TestClass> ConvertToGenericClass(NonGenericCollection collection) throws I 
    { 
     List<TestClass> newList = new ArrayList<TestClass> 
     for (Object object : collection){ 
      if(object instanceof TestClass){ 
       newList.add(object) 
       } else { 
       throw new IllegalArgumentException(); 
       } 
      } 
    return newList; 
    } 
} 
8

Một cách thanh lịch khác là tạo lớp bao bọc như thế này (tôi bao gồm điều này trong dự án tiện ích của tôi).

public class EnumerableGenericizer<T> : IEnumerable<T> 
{ 
    public IEnumerable Target { get; set; } 

    public EnumerableGenericizer(IEnumerable target) 
    { 
     Target = target; 
    } 

    IEnumerator IEnumerable.GetEnumerator() 
    { 
     return GetEnumerator(); 
    } 

    public IEnumerator<T> GetEnumerator() 
    { 
     foreach(T item in Target) 
     { 
      yield return item; 
     } 
    } 
} 

Bây giờ bạn có thể làm điều này:

IEnumerable<MyClass> genericized = 
    new EnumerableGenericizer<MyClass>(nonGenericCollection); 

Sau đó, bạn có thể quấn một danh sách chung bình thường xung quanh bộ sưu tập genericized.

+0

Giải pháp này phức tạp hơn nhưng hữu ích để giải quyết vấn đề mạnh hơn câu hỏi và câu trả lời khác. Khi vì một lý do nào đó, bộ sưu tập gốc được biết và sửa đổi bởi một số đối tượng khác và bạn chỉ muốn tạo ra một bộ sưu tập chung sẽ phản ánh những thay đổi trong tương lai. Hãy cẩn thận, mặc dù. Nó mất một số giao diện cấp cao hơn có thể cần thiết để xử lý hiệu quả, ví dụ như 'IList '. Nói cách khác, nếu hiệu suất là quan trọng (trong LINQ truy vấn ví dụ) nó sẽ phải được hoàn thành với những giao diện cấp cao hơn. –

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