2013-03-27 52 views
7

Tôi không thể xóa phần tử khỏi danh sách có thể liệt kê được, nhưng danh sách này là tham chiếu đến Danh sách, thuộc tính riêng tư của một lớp khác. Nếu tôi đặt personsCollection.Remove(theElement) trong cùng một lớp (trình quản lý lớp học), nó hoạt động hoàn hảo, nhưng tôi cần xóa phần tử đó khỏi lớp khác (lớp ManagerDelete). Làm thế nào tôi có thể làm điều này? Cảm ơn.Xóa phần tử khỏi danh sách chung

class Other 
{ 
    //Some code 
    public IEnumerable<Person> SearchByPhone (string value) 
    { 
     return from person in personCollection 
       where person.SPhone == value 
       select person; 
    } 
} 

class ManagerDelete 
{ 
//Some code 
IEnumerable<Person> auxList= SearchByPhone (value); 
//I have a method for delete here 
} 

class Manager 
{ 
//Some code 
private List<Person> personsCollection = new List<Person>(); 
} 

Trả lời

12

Bạn không thể xóa từ một IEnumerable<T> bạn cần để làm cho nó kiểu IList<T> để thêm/xoá các mục trực tiếp từ nó.

+1

'IList' là không cần thiết, 'ICollection' sẽ là đủ. – svick

1

Bạn có thể truyền IEnumerable thành IList. Điều này sẽ hoạt động nếu IEnumerable thực sự là một List. Tuy nhiên đây là một thiết kế tồi. Nếu bạn muốn xóa các mục, bạn nên hiển thị danh sách dưới dạng IList, không phải là IEnumerable.

1

An IEnumerable chỉ là giao diện để nói, tôi có bộ sưu tập này, bạn có thể lặp lại nó.

Nếu bạn có một cái nhìn tại các chi tiết thực tế của giao diện IEnumerable, nó không chứa nhiều, chỉ có một phương pháp để cho phép người gọi để lặp qua nó:

http://msdn.microsoft.com/en-gb/library/9eekhta0.aspx

Lý do tại sao List loại có thể cho phép bạn xóa chúng, là nó được xây dựng trên đầu trang của giao diện IEnumerable, mang lại cho bạn nhiều chức năng hơn. Nó được cho là đại diện cho một bộ sưu tập các đối tượng mà bạn có thể thao tác. Trong khi một IEnumerable chỉ đơn giản là không được thiết kế để làm điều này.

Phương pháp Remove thực sự bắt nguồn từ giao diện cơ bản ICollection rằng List cũng thực hiện:

http://msdn.microsoft.com/en-gb/library/bye7h94w.aspx

3

Darren là đúng. Nếu không chuyển đổi sang danh sách bạn có thể làm:

personCollection = personCollection.Except(SearchByPhone(value)); 

trong ManagerDelete.

+0

+1 để sử dụng Ngoại trừ, tuy nhiên hãy cảnh giác rằng bằng cách thay thế 'personCollection', bất kỳ đối tượng nào khác có tham chiếu đến' personCollection' sẽ vẫn trỏ vào cái cũ, điều này có thể được giải quyết bằng cách sử dụng [BindingSource] (http: //msdn.microsoft.com/en-us/library/system.windows.forms.bindingsource.aspx) hoặc lớp tương tự hoạt động như một hướng dẫn. –

4

Bạn cần hiểu giao diện IEnumerable cho phép bạn làm gì.

Tôi được liệt kê bên dưới danh sách Giao diện mà bạn nên sử dụng theo thiết kế, như và khi được yêu cầu trong các trường hợp khác nhau. Trong ví dụ của bạn IList là những gì bạn sẽ cần phải sử dụng.

  • ICollection Xác đặc điểm chung (ví dụ, kích thước, điều tra, và chủ đề an toàn) cho tất cả các loại thu thập không phải chung chung.

  • ICloneable Cho phép đối tượng thực hiện trả lại bản sao của chính nó cho người gọi.

  • IDictionary Cho phép đối tượng bộ sưu tập không chung chung đại diện cho nội dung
    sử dụng cặp khóa/giá trị của nó.

  • IEnumerable Trả về đối tượng triển khai giao diện IEnumerator (xem mục nhập bảng tiếp theo).

  • IEnumerator Bật tính năng lặp lại kiểu bộ sưu tập của mục bộ sưu tập.

  • IList Cung cấp hành vi để thêm, xóa và lập chỉ mục các mục trong một
    danh sách đối tượng tuần tự.

+0

Đừng quên có sự khác biệt giữa 'IList' và' IList ',' Danh sách' có thể thực hiện 'IList' nhưng các danh sách được đánh máy mạnh khác có thể không. –

2

Bạn có thể sử dụng để chuyển đổi các ToListIEnumerable đến một List và sau đó bạn có thể loại bỏ những thứ từ nó.

var auxList= SearchByPhone (value).ToList(); 
auxList.Remove(something); 
1

Ngoài câu trả lời khác: lựa chọn cấu trúc dữ liệu của bạn dường như chưa đủ. Nếu bạn thực sự có kế hoạch xóa các phần tử khỏi vùng chứa, vùng chứa của bạn không được là một số IEnumerable<> ngay từ đầu!

Hãy xem xét các lựa chọn sau:

  • switch IEnumerable<>-ICollection<>;
  • thay thế xóa bằng lọc ra (.Where()) và có được lọc riêng IEnumerable<>.
Các vấn đề liên quan