Tôi gặp trường hợp cổ điển là cố gắng xóa một mục khỏi bộ sưu tập trong khi liệt kê nó trong một vòng lặp:
List<int> myIntCollection = new List<int>();
myIntCollection.Add(42);
myIntCollection.Add(12);
myIntCollection.Add(96);
myIntCollection.Add(25);
foreach (int i in myIntCollection)
{
if (i == 42)
myIntCollection.Remove(96); // The error is here.
if (i == 25)
myIntCollection.Remove(42); // The error is here.
}
Khi bắt đầu lặp lại sau khi một thay đổi diễn ra, an InvalidOperationException
sẽ được ném ra, vì người điều tra không thích khi tập hợp cơ bản thay đổi.
Tôi cần thực hiện các thay đổi đối với bộ sưu tập trong khi lặp lại. Có nhiều mẫu có thể được sử dụng để tránh điều này , nhưng dường như không có mẫu nào trong số đó có giải pháp tốt:
Không xóa bên trong vòng lặp này, thay vào đó giữ một “Danh sách xóa” riêng biệt mà bạn xử lý sau vòng lặp chính.
Đây thường là một giải pháp tốt, nhưng trong trường hợp của tôi, tôi cần mục phải biến mất ngay lập tức khi "chờ đợi" cho đến sau vòng lặp chính để thực sự xóa mục sẽ thay đổi luồng logic của mã của tôi.
Thay vì xóa mục, chỉ cần đặt cờ trên mục và đánh dấu mục đó là không hoạt động. Sau đó, thêm chức năng của mẫu 1 để dọn dẹp danh sách.
Điều này sẽ hoạt động cho tất cả các nhu cầu của tôi, nhưng nó có nghĩa là rất nhiều mã sẽ phải thay đổi để kiểm tra cờ không hoạt động mỗi khi một mục được truy cập. Đây là quá nhiều quản lý đối với ý thích của tôi.
Bằng cách nào đó, kết hợp các ý tưởng của mẫu 2 trong một lớp bắt nguồn từ đó
List<T>
. Superlist này sẽ xử lý cờ không hoạt động, xóa các đối tượng sau khi thực tế và cũng sẽ không để lộ các mục được đánh dấu là không hoạt động cho người tiêu dùng trong danh sách. Về cơ bản, nó chỉ gói gọn tất cả các ý tưởng của mẫu 2 (và sau đó là mẫu 1).Một lớp học như thế này có tồn tại không? Có ai có mã cho điều này? đây có phải là cách tốt hơn không?
Tôi đã được thông báo rằng truy cập
myIntCollection.ToArray()
thay vìmyIntCollection
sẽ giải quyết vấn đề và cho phép tôi xóa bên trong vòng lặp.Đây có vẻ là một mẫu thiết kế xấu đối với tôi, hoặc có thể nó ổn?
Chi tiết:
Danh sách sẽ chứa nhiều mục và tôi sẽ chỉ xóa một số trong số chúng.
Bên trong vòng lặp, tôi sẽ thực hiện tất cả các loại quy trình, thêm, bớt, v.v., vì vậy giải pháp cần phải khá chung chung.
Mục mà tôi cần xóa có thể không phải là mục hiện tại trong vòng lặp. Ví dụ: tôi có thể đang ở mục 10 trong vòng lặp 30 mục và cần phải xóa mục 6 hoặc mục 26. Việc đi bộ ngược qua mảng sẽ không còn hoạt động vì điều này. ; o (