Bắt đầu với những lớp đơn giản này ...
Hãy nói rằng tôi có một tập hợp các lớp đơn giản như thế này:
class Bus
{
Driver busDriver = new Driver();
}
class Driver
{
Shoe[] shoes = { new Shoe(), new Shoe() };
}
class Shoe
{
Shoelace lace = new Shoelace();
}
class Shoelace
{
bool tied = false;
}
A Buscó a Driver, Drivercó hai Shoes, mỗi Shoecó a Shoelace. Tất cả đều rất ngớ ngẩn.
Thêm một đối tượng IDis Dùng cho Shoelace
Sau đó tôi quyết định rằng một số thao tác trên Shoelacecó thể là đa luồng, vì vậy tôi thêm một EventWaitHandlecho các luồng để giao tiếp. Vì vậy, Shoelacebây giờ trông như thế này:
class Shoelace
{
private AutoResetEvent waitHandle = new AutoResetEvent(false);
bool tied = false;
// ... other stuff ..
}
Triển khai IDis Dùng trên Dây giày
Nhưng bây giờ FxCop của Microsoft sẽ phàn nàn: "Triển khai IDis Dùng trên 'Dây giày' vì nó tạo ra các thành viên của các loại IDis Dùng sau: 'EventWaitHandle'."
Được rồi, tôi thực hiện IDisposabletrên Shoelacevà lớp nhỏ gọn của tôi trở nên lộn xộn khủng khiếp này:
class Shoelace : IDisposable
{
private AutoResetEvent waitHandle = new AutoResetEvent(false);
bool tied = false;
private bool disposed = false;
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
~Shoelace()
{
Dispose(false);
}
protected virtual void Dispose(bool disposing)
{
if (!this.disposed)
{
if (disposing)
{
if (waitHandle != null)
{
waitHandle.Close();
waitHandle = null;
}
}
// No unmanaged resources to release otherwise they'd go here.
}
disposed = true;
}
}
Hoặc (như được chỉ ra bởi các nhà bình luận) vì Shoelacebản thân nó không có tài nguyên không được quản lý, tôi có thể sử dụng triển khai xử lý đơn giản hơn mà không cần Dispose(bool)và Destructor:
class Shoelace : IDisposable
{
private AutoResetEvent waitHandle = new AutoResetEvent(false);
bool tied = false;
public void Dispose()
{
if (waitHandle != null)
{
waitHandle.Close();
waitHandle = null;
}
GC.SuppressFinalize(this);
}
}
Xem trong kinh dị khi lây lan IDis Dùng
Đúng là đã sửa. Nhưng bây giờ FxCop sẽ phàn nàn rằng Shoetạo ra một Shoelace, vì vậy Shoecũng phải như IDisposablevậy.
Và Drivertạo ra Shoenhư vậy Driverphải được IDisposable. Và Bustạo ra Drivernhư vậy Busphải được IDisposablevà như vậy.
Đột nhiên, sự thay đổi nhỏ của tôi Shoelacegây ra cho tôi rất nhiều công việc và ông chủ của tôi đang tự hỏi tại sao tôi cần phải kiểm tra Busđể thực hiện một thay đổi Shoelace.
Câu hỏi
Làm thế nào để bạn ngăn chặn sự lây lan này IDisposable, nhưng vẫn đảm bảo rằng các đối tượng không được quản lý của bạn được xử lý đúng cách?