2009-12-09 77 views
32

Xin lưu ý: Câu hỏi này là về sự khác biệt về thuật ngữ giữa các từ "destructor" và "finalizer" và cách sử dụng chính xác của chúng. Tôi đã chỉ cung cấp các ví dụ về việc sử dụng chúng trong C# và C++/CLI để chứng minh tại sao tôi hỏi câu hỏi đó. Tôi cũng nhận thức được cách nó được thực hiện trong cả C# và CLR, nhưng tôi hỏi về việc sử dụng đúng thuật ngữ.Sự khác biệt giữa destructor và finalizer?


Trong C# thế giới thuật ngữ "destructor" và "finalizer" dường như được sử dụng khá nhiều thay thế cho nhau, mà tôi nghi ngờ là vì C# đặc điểm kỹ thuật mô tả các chức năng dọn dẹp không xác định bằng cách sử dụng từ "destructor" , trong khi tài liệu CLR luôn sử dụng từ "finalizer", vì vậy trong các cõi của C# chúng có nghĩa là cùng một thứ.

Tuy nhiên, trong đặc tả C++/CLI, có sự khác biệt giữa hai loại. Nó cho phép xóa sạch xác định và không xác định và sử dụng thuật ngữ "destructor" cho chức năng xác định và "finalizer" cho chức năng không xác định:

Trình hoàn thiện cung cấp dọn dẹp không xác định. Một finalizer là một "cơ hội cuối cùng" chức năng được thực hiện trong quá trình thu gom rác, thường là trên một đối tượng có destructor đã không được thực thi.

Ngoài ra các mô tả Wikipedia của destructorfinalizer chỉ ra rằng hàm hủy và finalizers là những khái niệm riêng biệt, và hỗ trợ sử dụng spec của C++/CLI của các điều khoản liên quan đến định mệnh với:

Không giống như hàm hủy, finalizers là không xác định. Một destructor được chạy khi chương trình giải phóng một đối tượng một cách rõ ràng. Một finalizer, ngược lại, được thực thi khi hệ thống thu gom rác bên trong giải phóng đối tượng.

Những câu hỏi:

  • Có, từ một điểm khoa học máy tính xem, một sự khác biệt rõ ràng giữa một "destructor" và một "finalizer", hoặc là một cái gì đó thuật ngữ mà chỉ có thể được định nghĩa theo ngữ cảnh?

  • Nếu có sự khác biệt được xác định rõ ràng, thì tại sao thông số C# sử dụng thuật ngữ 'sai'?

Trả lời

36

1) Có sự khác biệt rõ ràng giữa "destructor" và "finalizer" được sử dụng trong ngành hoặc học viện không?

Chắc chắn có vẻ như vậy. Sự khác biệt dường như là các destructors là các phương thức dọn dẹp được gọi định nghĩa, trong khi finalizers chạy khi bộ thu gom rác cho chúng biết.

2) Trong trường hợp đó, thông số C# nhận được sai - finalizers được gọi là "destructors" trong C#. Tại sao các tác giả của C# spec làm cho nó sai?

Tôi không biết, nhưng tôi có thể đoán. Trong thực tế, tôi có hai dự đoán.

Đoán số 1 là vào ngày 12 tháng 5 năm 1999, không có bài viết wikipedia mô tả rõ ràng sự khác biệt tinh tế giữa hai khái niệm này. Đó là bởi vì không có một wikipedia. Nhớ lại khi không có wikipedia? Dark tuổi, người đàn ông. Lỗi có thể đơn giản là sai lầm trung thực, tin rằng hai thuật ngữ giống hệt nhau.Heck, cho tất cả tôi biết, hai điều khoản giống hệt nhau vào ngày 12 tháng 5 năm 1999 và sự khác biệt về định nghĩa chỉ được phát triển sau đó, vì rõ ràng là cần phải phân biệt giữa các phương pháp dọn dẹp mong muốn và lười biếng .

Đoán số 2 là vào ngày 12 tháng 5 năm 1999, ủy ban thiết kế ngôn ngữ muốn mở khả năng một "destructor" có thể được thực hiện dưới dạng một cái gì đó khác so với finalizer. Đó là, "destructor" được thiết kế để trở thành một khái niệm ngôn ngữ C# mà không nhất thiết phải ánh xạ một-với-một với khái niệm "finalizer" .NET. Khi thiết kế một ngôn ngữ cùng lúc với khung mà nó nằm trên đỉnh cũng đang được thiết kế, đôi khi bạn muốn cách nhiệt bản thân mình chống lại những thay đổi thiết kế phá vỡ muộn trong các hệ thống con của bạn.

ghi chú Ban ngôn ngữ cho 12 tháng 5 năm 1999 đọc trong phần:

Chúng ta sẽ sử dụng thuật ngữ "destructor" cho thành viên đó thực hiện khi một thể hiện được khai hoang. Các lớp học có thể có destructors; cấu trúc không thể. Không giống như trong C++, hàm hủy không thể là được gọi một cách rõ ràng. Tiêu hủy là không xác định - bạn không thể tin cậy biết khi nào trình phá hủy sẽ thực thi, ngoại trừ việc nói rằng nó thực thi tại một số điểm sau khi tất cả các tham chiếu đến đối tượng đã được giải phóng. Các destructor trong một chuỗi thừa kế được gọi theo thứ tự, từ hầu hết các hậu duệ của con cháu ít nhất. Có không cần (và không có cách nào) cho lớp bắt nguồn để gọi rõ ràng số cơ sở phá hủy. Trình biên dịch C# biên dịch các trình phá hủy thành biểu diễn CLR thích hợp . Đối với phiên bản này có thể có nghĩa là trình kết thúc phiên bản thể hiện là được phân biệt trong siêu dữ liệu. CLR có thể cung cấp bản tổng kết tĩnh trong tương lai ; chúng tôi không thấy bất kỳ rào cản nào đối với C# bằng cách sử dụng trình tổng kết tĩnh.

Vì vậy, giờ đây, bạn đã biết mọi thứ tôi biết về chủ đề này. Nếu bạn muốn biết thêm, hãy hỏi Anders lần sau khi bạn gặp anh ta.

+2

Thú vị; từ các ghi chú, nó chắc chắn có vẻ giống như lúc destructor thời gian đã không ngụ ý determinism vì vậy tôi nghĩ bạn có lẽ phải rằng đó là một sự phân biệt đã phát triển kể từ đó. –

4

Tôi tin 'destructor' là mã C# và 'finalizer' là phương thức CIL đã biên dịch. Trình biên dịch C# biến một destructor thành một finalizer.

CHỈNH SỬA: Để tiết lộ chi tiết hơn; Đặc tả ngôn ngữ C# định nghĩa một 'destructor' như là một phương thức C# instance trên một lớp. 'destructor', sau đó, là một phần của C# ngữ pháp - destructors là một đối tượng ngôn ngữ xuất hiện trong mã nguồn.

destructor là một thành viên thực hiện các hành động cần thiết để hủy bỏ một thể hiện của một lớp. Các trình phá hủy không thể có tham số, chúng không thể có các công cụ sửa đổi truy cập và chúng không thể được gọi một cách rõ ràng. Trình phá hủy cho một cá thể được gọi tự động trong khi thu thập rác.

'finalizer' là một thuật ngữ được sử dụng trong Thời gian chạy ngôn ngữ chung, ví dụ: gọi tới GC.WaitForPendingFinalizers() và nó đề cập đến mọi ngôn ngữ .net, không chỉ C#. Bất kỳ loại tham chiếu .net nào đều có thể có trình kết thúc. Đối với một lớp C# (tạo phẩm mã nguồn), trình phá hủy biên dịch thành phương thức CIL, đó là trình kết thúc kiểu của CLR.

Hoặc ngắn gọn hơn, destructorfinalizer như mã nguồnmã máy;)

+0

Tôi biết rằng họ ánh xạ tới cùng một thứ. Tôi đã hỏi về việc sử dụng đúng thuật ngữ. –

+0

Xin chào, Greg. Tôi đã không nói về họ lập bản đồ cho cùng một điều; nơi có một ý nghĩa của tôi là một thuật ngữ đề cập đến một vật phẩm mã nguồn, và thuật ngữ kia ám chỉ đến vật phẩm mã máy đã biên dịch. Các cấu trúc được đề cập trong thông số ngôn ngữ C# và là một phần của ngữ pháp C#; Finalizers thì không. Tuy nhiên, thu gom rác thải (là ngôn ngữ bất khả tri) đề cập đến các nhà tổng hợp; ví dụ, trong các cuộc gọi như GC.WaitForPendingFinalizers(); do đó, Finalizer là một thuật ngữ CLR, và đề cập đến quá trình làm sạch trước khi phát hành bộ nhớ của một đối tượng .net. Tôi sẽ cố gắng sửa bài của mình để làm rõ nó ở đó, quá –

+0

C# không có destructors, chỉ finalizers. Thực tế là nó chia sẻ một cú pháp tương tự với C++ 's destructor không quan trọng. – user7116

3

Nếu chúng ta tuân thủ với "xác định" định nghĩa của hàm hủy, sau đó tôi sẽ nói rằng trong các đối tượng .NET không có destructors trừ khi được thực thi một cách rõ ràng bằng cách sử dụng the IDisposable interface.

7

Nói đúng C# không có hàm hủy (tôi tin rằng thông số C# khó hiểu ở điểm này). Trình hoàn thiện của C# trông giống như một trình phá hủy C++ nhưng, như bạn nói, là không xác định. C# có khả năng dọn sạch xác định ở dạng IDisposable::Dispose (nhưng điều này vẫn không được gọi là một destructor).

C++/CLI có các trình phá hủy xác định, trông giống như trình phá hủy C++. Ở cấp CLI, những bản đồ này vào IDisposable::Dispose() (IDisposable được triển khai cho bạn). C++/CLI có các finalizers không xác định, trông giống như destructors nhưng sử dụng! tiền tố thay vì tiền tố ^. Thực tế là C++/CLI sử dụng cùng một cú pháp cho các destructor mà C# sử dụng cho finalizers có thể hơi khó hiểu - nhưng nó phù hợp hơn với C++, có truyền thống hủy diệt xác định mạnh mẽ.

Thật không may là việc thiếu định nghĩa chung của các điều khoản này có nghĩa là bạn luôn cần phải làm rõ những gì bạn đang nói đến. Cá nhân tôi luôn sử dụng từ finalizer khi nói về khái niệm C# và đặt destructor cho các ngữ cảnh, nơi nó chắc chắn ngụ ý hủy diệt xác định.

[Cập nhật] Vì bài đăng gốc của tôi ở đây Eric Lippert đã đăng phản hồi của mình (câu trả lời được chấp nhận) và theo dõi với số blog post giống nhau. Tôi vui mừng khi thấy chúng tôi đồng ý :-)

+1

'Vấn đề' là C# gọi nó là một destructor. –

+1

Vâng, tôi nhớ lại rằng sau lần đầu tiên tôi trả lời - nó sử dụng cả hai thuật ngữ - vì thế tôi nhận xét thêm về nó là khó hiểu. Đó là cả hai rõ ràng hơn và vẫn chính xác để gọi cho họ finalizers. – philsquared

+0

+1 Tôi nghĩ đây là câu trả lời hay nhất. Có vẻ như thông số C# hơi gây nhầm lẫn với các thuật ngữ của nó. Có thể nó được viết bởi một thực tập sinh: P – SwDevMan81

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