Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
434 views
in Technique[技术] by (71.8m points)

garbage collection - C# - Are objects immediately destroyed when going out of scope?

Can I trust that an object is destroyed and its destructor is called immediately when it goes out of scope in C#?

I figure it should since many common coding practices (e.g. transaction objects) rely on this behaviour, but I'm not very used to working with garbage collection and have little insight to how such languages usually behave.

Thanks.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Nope, .Net and hence C# relies on a garbage collection memory management. So destructors (which in .Net is called finalizers) are not called until GC finds it proper to destroy the objects.

Additionally: most "regular" objects in C# don't have destructors. If you need the destructor pattern you should implement the IDisposable interface with the Dispose Pattern. On disposable objects you should also make sure that the Dispose method gets called, either with the using keyword or directly calling the method.

To further (hopefully) clarify: deterministic disposal is useful in .Net e.g. when you need to explicitly free resources that is not managed by the .Net runtime. Examples of such resources are file handles, database connections, etc. It is usually important that these resources be freed as soon as they no longer are needed. Thus we cannot afford to wait for the GC to free them.

In order to get deterministic disposal (similar to the scope behavior of C++) in the non-deterministic world of the .Net GC, the .Net classes rely on the IDisposable interface. Borrowing from the Dispose Pattern, here are some examples:

First, instantiating a disposable resource and then letting the object go out of scope, will leave it up to the GC to dispose the object:

1.    {
2.       var dr = new DisposableResource();
3.    }

To fix this we can explicitly dispose the object:

1.    {
2.       var dr = new DisposableResource();
3.
4.       ...
5.
6.       dr.Dispose();
7.    }

But what if something goes wrong between line 2 and 6? Dispose will not be called. To further ensure that Dispose will finally be called regardless of any exceptions we can do the following:

1.    var dr = new DisposableResource();
2.    try
3.    {
4.       ...
5.    }
6.    finally
7.    {
8.       dr.Dispose();
9.    }

Since this pattern is often needed, C# includes the using keyword to simplify things. The following example is equivalent to the above:

1.    using (var dr = new DisposableResource())
2.    {
3.       ...
4.    }

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...