2010-07-16 18 views
7

Tôi cần một cách để theo dõi các phiên bản của các lớp khác nhau, mà không có các lớp đó có bất kỳ kiến ​​thức nào về việc chúng đang được theo dõi. Về cơ bản, tôi có một nhà máy sản xuất lớp học tạo ra các trường hợp và đưa chúng ra một chủ đề khác. Khi chuỗi đó hoàn thành và dỡ bỏ cá thể, tôi cần được thông báo về điều đó để tôi có thể thực hiện tính toán tham chiếu và thoát khỏi nhà máy của lớp khi tất cả các phiên bản đã biến mất.Nhận thông báo về việc xử lý/tiêu hủy đối tượng

Thách thức là tôi không thể sửa đổi bất kỳ lớp nào tôi sẽ tải, vì tôi không kiểm soát mã nguồn của chúng.

Theo dõi các trường hợp tôi tạo đơn giản, tôi có thể đặt chúng vào một số loại bộ sưu tập khi tạo chúng. Theo dõi sự hủy diệt của họ đang gây ra vấn đề cho tôi. Nếu tôi có thể sửa đổi mã nguồn, tôi sẽ thêm một sự kiện vào mỗi lớp và khi tôi tạo một cá thể, tôi sẽ móc vào sự kiện và sử dụng nó làm thông báo của tôi. Nhưng tôi không thể làm điều đó.

Vì vậy, câu hỏi đặt ra là: có cách nào lén lút để theo dõi một cá thể đối tượng và phát hiện khi nó đang bị phá hủy không?

Trả lời

3

Không có cách nào để nhận thông báo hoạt động, nhưng bạn có thể giữ WeakReference cho các đối tượng và định kỳ kiểm tra xem có bất kỳ đã chết hay không.

Chỉnh sửa: Tôi thích câu trả lời của Reed tốt hơn của tôi!

+0

+1 Thật buồn cười - tôi đã nghĩ chính xác điều này, cho đến khi tôi đọc phần mà anh ấy nói anh ta đang kiểm soát việc xây dựng các vật thể;) –

+0

Điều này thực sự có vẻ là giải pháp khả thi nhất trong tình huống của tôi, tôi ' tôi sẽ thử. –

+0

Tôi thích của bạn tốt hơn so với Reed bởi vì nó có nghĩa là khách hàng của những loại không cần phải biết về một loại trang trí đặc biệt –

0

Làm thế nào về bạn kiểm soát sự phá hủy của các đối tượng:

public void Destroy(T obj) 
{ 
    if (obj == null) 
     throw new ArgumentNullException("obj"); 
    if (!_living.Contains(obj)) 
     throw new ArgumentException("Where did this obj come from?"); 

    using (obj as IDisposable) 
    { 

    } 

    _living.Remove(obj); // List? 
} 
+0

Vì vậy, những gì gọi là tiêu diệt()? Hãy nhớ rằng tôi không thể kiểm soát các loại tôi đang tải (trên thực tế chúng được nạp tự động từ một thư mục và tôi không biết trước những gì tôi sẽ tìm thấy ở đó). –

10

Vì bạn đang tạo các đối tượng, nó có vẻ như bạn có thể trả về một Decorator thay cho ví dụ thực tế.

Bằng cách sử dụng Decorator Pattern, bạn có thể "bọc" đối tượng được trả lại trong API được trang trí của riêng bạn. Các trang trí có thể cung cấp một triển khai IDisposable cung cấp thông báo hủy diệt của bạn.

+0

Điều này thật tuyệt. Bạn có thể sử dụng refection để tạo trang trí cho. Điều này sẽ rất quan trọng nếu lớp học lớn. – ChaosPandion

+0

Điều đó rất thú vị, tôi sẽ theo dõi điều này. Cảm ơn. –

2

Nếu bạn giữ một danh sách các tài liệu tham khảo để các trường hợp bạn tạo họ sẽ không được thu gom rác thải và do đó sẽ không bao giờ bị hủy diệt ...

Thay vào đó bạn có thể tạo ra một kho lưu trữ chứa một danh sách các Guids và tạo một hướng dẫn mới cho mỗi cá thể và sau đó thêm nó vào danh sách thay thế - một cái gì đó giống như một FactoryRepository. Bằng cách này, bạn không có vấn đề tham chiếu đối với việc thu thập rác vì Guids là cấu trúc chứ không phải là các kiểu tham chiếu. Sau đó bạn có thể kế thừa từ mỗi lớp để tạo một loại có thể thông báo về việc hủy. Tôi giả định rằng vì bạn không thể thay đổi mã của các lớp gốc, bạn cũng không thể thay đổi người tiêu dùng của các lớp này, do đó một cái gì đó giống như mẫu trang trí (thông qua một giao diện) là do các loại sẽ không tương thích.

Rất đơn giản ví dụ:

public class OriginalClassDestroyNotifier : OriginalClass 
{ 
    private readonly Guid _instanceId; 

    public OriginalClassDestroyNotifier(Guid instanceId) 
    { 
     _instanceId = instanceId; 
    } 

    ~OriginalClassDestroyNotifier() 
    { 
     FactoryRepository.NotifyDestroyed(_instanceId); 
    } 
} 
Các vấn đề liên quan