Sample use of a C# Destructor

跟風遠走 提交于 2019-12-05 12:09:50

Finalizers are very rarely needed now. They used to be required when you had direct access to native resources - but now you should usually be using SafeHandle instead.

Joe Duffy has an excellent post about this which goes into rather more details than I would be able to write myself - so go read it :)

A quick note on terminology: the ECMA version of the C# spec refers to them as finalizers; the Microsoft version of the spec has always referred to them as destructors and continues to do so.

They're finalizers, not destructors. They're often used to clean up unmanaged resources - if you wrote your own file class, then you would need to use the finalizer to clean up the native file handle.

Finalizers are rarely needed in C# and adding one can cause the garbage collector to take longer to clean up the garbage as an extra pass is required to run the finalizer. Instead you should normally use the IDisposable pattern.

An example usage of a finalizer is if you suspect resource leakage you can use it when debugging to check if Dispose has been called correctly before the object is garbage collected. If an object that holds unmanaged resources has its finalizer called before Dispose has been called it could be a sign of a resource leakage. But since the finalizer may not ever be called it should not contain any application critical logic.

What do you mean by destructor? C# has

  • The IDisposable pattern which you'd use for deterministic destruction
    Useful to close Handles when you don't need them anymore. So they are closed now and not whenever the GC decides to collect the object which might be much later or not at all.
    Or in pure managed code to tell an object to remove itself from the object graph, unsubscribe from events,...
    Commonly used with a using statement
  • The Finalizer which is almost useless. It runs at an unknown time, it might not run at all,...
    The only thing I use it for is to remind me that I forgot to call Dispose on something
    While it has the syntax of a C++ destructor I don't consider it the equivalent of a C++ destructor. I prefer to think about Dispose() as the destructor.
  • Critical finalization and SafeHandles which you use for native resources

I think instead of the pattern you posted modern code should own a private SafeHandle and call it's Dispose method in it's own Dispose.

C# doesn't have 'destructors' as you're probably thinking about them. With .NET's garbage collector, object collection won't happen right away when your class goes out of scope.

I think what you're more interested in is the IDisposable pattern. That is a deterministic way for you to clean up resources your object uses.

In addition, .NET classes can have 'finalizers' which are executed when an object is collected. It can be used to call dispose if the original caller of your object neglected to.

But, implementing a finalizer in your class queues it up for special processing for GC and might have a performance impact.

The IDisposable interface provides a method to use as a destructor/finalzer.

What I mean is that you may implement the IDisposable interface in order to free the resources your object is using. As the others have said, this is not the same thing as a good old destructor, since the Dispose() method will not be called directly by yourself, but by the managed code to dispose of your object after a while.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!