2009-11-26 30 views
13

Hai phần này:Tại sao các lớp tĩnh không có destructors?

  1. Nếu một lớp tĩnh có thể có một constructor tĩnh, tại sao có thể không nó có một destructor tĩnh?

  2. Giải pháp tốt nhất là gì? Tôi có một lớp tĩnh quản lý một nhóm các kết nối được các đối tượng COM, và tôi cần phải chắc chắn rằng các kết nối của họ bị đóng/phát hành nếu có điều gì đó phát sinh ở đâu đó trong chương trình.

Trả lời

18

Thay vì một lớp tĩnh, bạn nên sử dụng một lớp bình thường với mẫu đơn (có nghĩa là, bạn giữ một cá thể duy nhất của lớp, có lẽ được tham chiếu bởi một thuộc tính tĩnh trên chính lớp đó). Sau đó, bạn có thể có một destructor, hoặc thậm chí tốt hơn, một sự kết hợp của destructor và phương pháp Dispose.

Ví dụ, nếu bây giờ bạn có:

static class MyClass 
{ 
    public static void MyMethod() {...} 
} 

//Using the class: 
MyClass.MyMethod(); 

bạn sẽ phải thay:

class MyClass : IDisposable 
{ 
    public static MyClass() 
    { 
     Instance=new MyClass(); 
    } 

    public static MyClass Instance {get; private set;} 

    public void MyMethod() {...} 

    public void Dispose() 
    { 
     //... 
    } 

    ~MyClass() 
    { 
     //Your destructor goes here 
    } 
} 

//Using the class: 
MyClass.Instance.MyMethod(); 

(Chú ý các trường hợp được tạo ra trong constructor tĩnh, mà được gọi lần đầu tiên bất kỳ thành viên tĩnh lớp nào được tham chiếu)

+1

Cảm ơn bạn. Tôi cũng đã thêm vào mã của tôi một hàm tạo riêng không tĩnh để lớp không thể được khởi tạo ở nơi khác. –

+0

Nếu luồng sẽ được sử dụng, cần phải làm cho chuỗi an toàn. –

+1

Có một hướng dẫn tốt ở đây về tất cả các cách khác nhau để làm Mẫu Singleton với an toàn chỉ. http://csharpindepth.com/Articles/General/Singleton.aspx – Naz

3

1. Tại sao? - Một loại không thể có một hàm tạo cho mỗi se như cách bạn thường nghĩ về các hàm tạo trên các cá thể. Nói chung nó đôi khi được gọi là phương thức "initializer static" nhưng Microsoft sử dụng thuật ngữ "type constructor" (và nó có các hạn chế đặc biệt) - bạn đặt mã vào nó để init kiểu/class - nếu nó là một constructor instance nó có thể quá tải. Giới hạn tĩnh này trên "constructor kiểu" là vì .NET CLR chịu trách nhiệm nạp mẫu lớp trên heap và không cho phép các tham số được xác định trong trường hợp này (vì bạn sẽ bao giờ vượt qua đối số) như thế nào. Bởi vì theo nghĩa hẹp nhất, lập trình viên không chịu trách nhiệm gây ra constructor kiểu được gọi, nó sẽ không có ý nghĩa nhiều để cho phép lập trình viên mã một destructor tĩnh khi nó có nhiều hơn trong miền của CLR. CLR cuối cùng sẽ loại bỏ mẫu lớp khỏi heap, nhưng tuổi thọ của mẫu lớp dài hơn các trường hợp của nó, vì vậy bạn sẽ không muốn làm bất kỳ tài nguyên nào chuyên sâu vào nó (ví dụ: giữ mở một kết nối db).

2. Cái gì? - Singleton Nếu bạn đang gặp một tình huống mà bạn cảm thấy bạn cần phải mở một tài nguyên trên mẫu lớp và hủy nó sau đó, bạn có thể xem xét Singleton software pattern để chỉ có một thể hiện của lớp đó và có thể thực hiện giao diện System.IDiposable viện trợ với dọn dẹp, ngoài các destructor. (Tôi thấy ai đó đã đánh bại tôi với mẫu mã IDisposable đầu tiên, vì vậy tôi sẽ kết thúc giải pháp của tôi ở đây.)

7
  1. Lớp tĩnh không có trình phá hủy vì một lớp tĩnh không bao giờ bị phá hủy.

  2. Nếu bạn muốn tạo và hủy nhiều phiên bản, nó không được tĩnh. Làm cho nó trở thành một lớp học đầy đủ.

  3. Các cấu trúc không được sử dụng cho mục đích này. Sử dụng IDisposable/Dispose.

+0

Tại sao trình biên dịch cho phép bạn có một mặc dù? 'static ~ ClassName() {}' hiện nó chưa bao giờ chạy? – Zapnologica

1

Lớp tĩnh không bao giờ bị hủy. Nó kết thúc cùng với chương trình. Bạn có thể sử dụng mẫu đơn như một sự thực hiện thay vì sử dụng một lớp tĩnh

+0

Bạn có chắc chắn một Class (loại) không phải là rác được thu thập? –

+0

@HenkHolterman Có. Không có gì để thu thập. Vì tất cả các thuộc tính/trường có ít nhất một tham chiếu (lớp tĩnh) và vì phạm vi của lớp tĩnh là từ lần truy cập đầu tiên cho đến khi chương trình bị chấm dứt, không có gì để thu thập –

Các vấn đề liên quan