2010-09-02 29 views
8

Tôi có một chức năng được gọi nếu danh sách đã thay đổi kể từ khi nó được gọi lần cuối, cách tốt nhất để thực hiện điều này là gì?Phương pháp kiểm tra tối ưu cpu tối thiểu nếu danh sách đã thay đổi trong C#

ví dụ:

List<A> OurList = new List<A>(); 
private void Update() 
{ 
    Boolean Changed = //?  
    if(Changed) CheckList(OurList); 
} 

tôi sẽ giả làm một biến để lưu trữ các danh sách cũ và so sánh, nhưng làm thế nào tôi sẽ cập nhật danh sách cũ vào danh sách mới mà không cần sao chép nó tất cả ra? (Nếu tôi chỉ định, nó cũng sẽ cập nhật "danh sách cũ")

Trả lời

13

Cách hiệu quả nhất là quấn List<> trong lớp của riêng bạn và có tất cả các phương thức thay đổi (Thêm, Xóa) đặt cờ boolean .

Phương pháp của bạn sau đó có thể chỉ cần nhìn vào lá cờ đó và đặt lại.

+3

Cũng có thể có một số loại hệ thống nghe sự kiện thông báo cho các bên quan tâm khi bộ sưu tập đã thay đổi. – Carlos

+0

Điều này nghe có vẻ giống như cách tốt nhất, tôi đoán nó sẽ dễ dàng hơn nhiều để có một bộ sưu tập tùy chỉnh cho một vài điều mà tôi hiện đang sử dụng danh sách cho. Cảm ơn :) – Blam

1
  • Hạn chế quyền truy cập vào danh sách.
  • Chỉ cho phép thay đổi thông qua API được chỉ định.
  • Trong API đó, hãy đặt cờ bất cứ khi nào phương thức ChangeList được gọi.
1

Bạn đang cố gắng xem liệu chính Danh sách đã thay đổi (thêm/xóa mục) hay nếu một mục trong danh sách thay đổi.

Nếu bạn chỉ muốn xem danh sách có thêm/xóa mục hay không, cách dễ nhất là bọc Danh sách trong một lớp mới và ghi đè các phương thức Thêm/Loại bỏ cho đối tượng của bạn để kích hoạt một boolean.

Yêu cầu phức tạp hơn là nếu bạn cần biết một mục có trong danh sách đã thay đổi hay không (thuộc tính hoặc trường trong đối tượng lớp được tham chiếu trong danh sách). Nếu đó là trường hợp, nó phụ thuộc vào tình hình cụ thể của bạn. Bạn có thể đặt trong setter cho các thuộc tính cho các lớp đó một cách để kích hoạt một boolean sẽ làm điều tương tự như trước đây. Nhưng điều này phụ thuộc vào độ phức tạp của lớp trong danh sách chung.

5

Nếu bạn đang sử dụng .NET 4.0, bạn có thể sử dụng lớp ObservableCollection. (trước 4.0, bạn cần tham khảo WPF).

Khi bạn tạo danh sách của mình, chỉ cần thêm trình xử lý vào sự kiện CollectionChanged.

+0

Tham khảo WPF không phải là lý tưởng và có .NET 3.5 là một yêu cầu, nhưng cảm ơn anyway :) – Blam

19

Sử dụng ObservableCollection<T> thay vì Danh sách, sau đó đăng ký sự kiện CollectionChanged.

Bằng cách này, bạn sẽ được thông báo khi danh sách được thay đổi thay vì phải quét dữ liệu để tìm hiểu điều gì đã xảy ra sau sự kiện.

+0

chúng tôi nghĩ như nhau và trong một khung thời gian tương tự. Khoảng một phút rưỡi khác nhau. – Robaticus

+3

+1: Tại sao cuộn của riêng bạn khi có một triển khai hoàn toàn tốt có sẵn? Xem thêm [NotifyCollectionChangedEventArgs] (http://msdn.microsoft.com/en-us/library/system.collections.specialized.notifycollectionchangedeventargs_members.aspx). –

+0

trên .Net 3.5, nhưng cảm ơn anyway :) – Blam

2

Đặt cược tốt nhất của bạn sẽ là sử dụng số ObservableCollection<T> hoặc BindingList<T> để nhận thông báo đẩy về thay đổi. Bạn cũng có thể phân lớp Collection<T> nếu bạn muốn bất kỳ hành vi tùy chỉnh nào.

Để trả lời câu hỏi của bạn theo yêu cầu (ngoại trừ bit chuyên sâu CPU), bạn có thể sử dụng tính năng hiện có của List<T>: nó duy trì phiên bản nội bộ của riêng nó để nó có thể ném nếu bộ sưu tập đã thay đổi trong quá trình liệt kê.

Điều này được dựa trên phân tích mã từ phản xạ. Nó không phải là một phần của bất kỳ hợp đồng, do đó, nó có trách nhiệm phá vỡ bất cứ lúc nào. Nó cũng có thể không hoạt động trong môi trường một phần tin cậy.Vui lòng sử dụng cẩn thận:

public static int GetVersion<T>(this List<T> list) 
{ 
    return (int)list.GetType() 
        .GetField("_version", BindingFlags.Instance | BindingFlags.NonPublic) 
        .GetValue(list); 
} 

... 

private int _lastCheckedVersion = 0; 

private void Update() 
{ 
    int currentVersion = ourList.GetVersion(); 

    if(currentVersion != _lastCheckedVersion) CheckList(ourList); 

    _lastCheckedVersion = currentVersion; 
} 
Các vấn đề liên quan