2011-11-28 11 views
7

Chỉ cần tò mò, tại sao gọi IEnumerable.ToList() trên Danh sách hiện có không trả về cùng một cá thể? Tương tự áp dụng cho IEnuerable.ToArray(). Điều này sẽ không tốt hơn từ quan điểm tiêu thụ bộ nhớ?.NET Tại sao IEnumerable.ToList() trên Danh sách hiện có tạo mảng mới

Tôi chạy các test nhanh sau:

var things= new List<Thing>(new [] {new Thing(), new Thing()}); 
     Console.WriteLine(things.GetHashCode()); 

     things= things.ToList(); 
     Console.WriteLine(things.GetHashCode()); 

Và tôi nhận được trường hợp đối tượng khác nhau. Tại sao không chỉ đơn giản là cùng một trường hợp?

Trả lời

9

Điều này được cố ý thực hiện để cho phép cho trường hợp "danh sách sao chép".

Ví dụ: tôi làm foreach(var a in list) list.Remove(a), tôi sẽ nhận được ngoại lệ cho biết rằng "bộ sưu tập đã được sửa đổi" trong khi điều tra đang được tiến hành.

Để khắc phục điều này, tôi thực hiện: foreach(var a in list.ToList()) list.Remove(a).

Nếu bạn muốn ngữ nghĩa dọc theo dòng "chuyển đổi thành danh sách nếu nó chưa phải là một", bạn sẽ phải tự xử lý nó. Trong thực tế, bạn thực sự có thể viết một phương pháp khuyến nông gọn gàng cho việc này:

public static IList<T> ToListIfNotAlready(this IEnumerable<T> source) 
{ 
    var list = source as IList<T>; 
    return list == null ? source.ToList() : list; 
} 

Vâng, đó có thể là cách khác xung quanh, nhưng các nhà thiết kế LINQ chọn phương pháp này, và có mọi quyền để làm như vậy, như không phương pháp tiếp cận có lợi thế riêng biệt trong trường hợp chung.

+0

Tôi thích phần mở rộng, cảm ơn. –

1

Vì bạn không thể sửa đổi nội dung của một điều tra trong khi nó được liệt kê, có những lúc bạn cần tạo bản sao của danh sách để bạn có thể lặp qua một bản sao và sửa đổi bản sao kia. ToList() được định nghĩa là trả về một danh sách mới độc lập với danh sách gốc.

0

Hành vi của ToList() không liên quan gì đến việc liệt kê. Nó có ý nghĩa gì, nghĩa là nó trả về một danh sách. Nó không ngụ ý nó trả về cùng một danh sách với mọi cuộc gọi; nếu không thì; thể hiện danh sách sẽ phải được lưu trữ nội bộ ở đâu đó. Tương tự với nhiều chức năng khác của LINQ. Thực tế là nó trả về một danh sách mới có lợi cho việc sử dụng với điều tra viên.