473,662 Members | 2,524 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

C# Destructor Blueprint

Joe
I am looking for the quintessential blueprint for how a
C++ like destructor should be implemented in C#. I see
all kinds of articles in print and on the web, but I see
lots of discrepencies. For example ...

C# Essentials (O'Reilly) - "Finalizers are class-only
methods". Not sure what "class-only method" means in this
context, but ususally I would assume that to mean it is
static and would only be called once for the life of the
program, and not once for every object of that class. Am
I reading this correctly? Is it just plain wrong? Will
the Finalize method be called once for every object?

Can an object's destructor/finalizer be called explicitly
by your code? Programming C# (O'Reilly) says no on page
80. Yet on MS site
(http://msdn.microsoft.com/library/default.asp?
url=/library/en-us/dncscol/html/deepc10192000.a sp?
frame=true) they say yes, search for "One simple solution
is to make the finalizer calls explicit" on that page.

So, lets assume I have a handle to an unmanaged resource
(intentionally vague), where exactly should I put my code
to free/close the handle? In the Finalize() or Dispose()?

As you can see, I have a poor understanding of the proper
way to do this. I have read lots of articles, but cannot
find any that actually look correct to me.

Thanks.

Nov 15 '05 #1
4 3801
The only real difference between the C++ destructor and the C#/.NET
destructor is that in .NET, you have not control over when the "finalizer"
is called.

I do not believe the C# compiler will let you call the Finalize method
directly, but other languages may.

In the destructor, you simply put whatever code you need to release
resources.

It may be a good idea to include both a destructor (Finalize) and a Dispose
method. What you would do is put the logic in the Dispose method and simply
have the Finalize method call the Dispose method. That way you can choose
to manually dispose of the resources, or wait for the GC to do it.

Destructors are instance specific just like normal constructors. They have
to be since the whole purpose is the resource resources that were allocated
within an object instance.

"Joe" <jo*******@genp t.com> wrote in message
news:1e******** *************** ******@phx.gbl. ..
I am looking for the quintessential blueprint for how a
C++ like destructor should be implemented in C#. I see
all kinds of articles in print and on the web, but I see
lots of discrepencies. For example ...

C# Essentials (O'Reilly) - "Finalizers are class-only
methods". Not sure what "class-only method" means in this
context, but ususally I would assume that to mean it is
static and would only be called once for the life of the
program, and not once for every object of that class. Am
I reading this correctly? Is it just plain wrong? Will
the Finalize method be called once for every object?

Can an object's destructor/finalizer be called explicitly
by your code? Programming C# (O'Reilly) says no on page
80. Yet on MS site
(http://msdn.microsoft.com/library/default.asp?
url=/library/en-us/dncscol/html/deepc10192000.a sp?
frame=true) they say yes, search for "One simple solution
is to make the finalizer calls explicit" on that page.

So, lets assume I have a handle to an unmanaged resource
(intentionally vague), where exactly should I put my code
to free/close the handle? In the Finalize() or Dispose()?

As you can see, I have a poor understanding of the proper
way to do this. I have read lots of articles, but cannot
find any that actually look correct to me.

Thanks.

Nov 15 '05 #2
Hi Joe,

"Joe" <jo*******@genp t.com> wrote in message
news:1e******** *************** ******@phx.gbl. ..
I am looking for the quintessential blueprint for how a
C++ like destructor should be implemented in C#. I see
all kinds of articles in print and on the web, but I see
lots of discrepencies. For example ...

C# Essentials (O'Reilly) - "Finalizers are class-only
methods". Not sure what "class-only method" means in this
context, but ususally I would assume that to mean it is
static and would only be called once for the life of the
program, and not once for every object of that class. Am
I reading this correctly? Is it just plain wrong? Will
the Finalize method be called once for every object?
I'm not sure what "class-only" means in this case, but finalizers are
*not* static. If a finalizer has been defined for a class then it will be
called for every instance of that class unless it has been suppressed or in
other unusual circumstances (the app process is terminated, etc.).
Can an object's destructor/finalizer be called explicitly
by your code? Programming C# (O'Reilly) says no on page
80. Yet on MS site
(http://msdn.microsoft.com/library/default.asp?
url=/library/en-us/dncscol/html/deepc10192000.a sp?
frame=true) they say yes, search for "One simple solution
is to make the finalizer calls explicit" on that page.
According to the docs on Object.Finalize , you may only explicitly call
the Finalize method of a base class.
So, lets assume I have a handle to an unmanaged resource
(intentionally vague), where exactly should I put my code
to free/close the handle? In the Finalize() or Dispose()?


This article covers the topic pretty well, I think:
http://tinyurl.com/2k6e (MSDN)

Basically a finalizer is an absolute last resort. Put your resource
deallocation code in another method and call it from either the Finalizer or
IDisposable.Dis pose. Then the only other thing to do is to call
"GC.SuppressFin alize(this);" from IDisposable.Dis pose so that the object
isn't "finalized" unnecessarily.

Regards,
Dan
Nov 15 '05 #3
Joe,

See
http://msdn.microsoft.com/msdntv/epi...A/manifest.xml
for an MSDN TV episode on the IDisposable interface and the use of
finalizers. The "related resources" listed on the page might also be
helpful.

HTH,
Nicole
"Joe" <jo*******@genp t.com> wrote in message
news:1e******** *************** ******@phx.gbl. ..
I am looking for the quintessential blueprint for how a
C++ like destructor should be implemented in C#. I see
all kinds of articles in print and on the web, but I see
lots of discrepencies. For example ...

C# Essentials (O'Reilly) - "Finalizers are class-only
methods". Not sure what "class-only method" means in this
context, but ususally I would assume that to mean it is
static and would only be called once for the life of the
program, and not once for every object of that class. Am
I reading this correctly? Is it just plain wrong? Will
the Finalize method be called once for every object?

Can an object's destructor/finalizer be called explicitly
by your code? Programming C# (O'Reilly) says no on page
80. Yet on MS site
(http://msdn.microsoft.com/library/default.asp?
url=/library/en-us/dncscol/html/deepc10192000.a sp?
frame=true) they say yes, search for "One simple solution
is to make the finalizer calls explicit" on that page.

So, lets assume I have a handle to an unmanaged resource
(intentionally vague), where exactly should I put my code
to free/close the handle? In the Finalize() or Dispose()?

As you can see, I have a poor understanding of the proper
way to do this. I have read lots of articles, but cannot
find any that actually look correct to me.

Thanks.

Nov 15 '05 #4
Joe wrote:
I am looking for the quintessential blueprint for how a
C++ like destructor should be implemented in C#. I see
all kinds of articles in print and on the web, but I see
lots of discrepencies. For example ...
Native C++ destructors are used to release resources, and they are called
when an object is deleted either explicitly (through the delete operator) or
when a stack allocated object goes out of scope. In general the stack
object's lifetime will be at maximum the scope of the method where the
variable is declared, but native C++ also allows global objects.

..NET does not have global objects, nor does it have stack allocated objects.
C# does not have a delete operator (C++ does, even for .NET objects).

The C# destructor provides the code for the Finalizer, in general you should
avoid implementing a Finalizer when you can. The reason is that you do not
know when the Finalizer will be called, it could be in a few minutes or in a
few hours. Native C++ destructors are generally used to release resources
used by an object, and the implication is that those resources may be needed
by other code, so you want them released as soon as possible. For this
reason Microsoft came up with the Dispose pattern and IDisposable: the
developer puts the code to release the resources in Dispose. Of course, that
does mean that the user has a responsibility to call Dispose, so you can
create a destructor (Finalizer) that calls Dispose because releasing
resources late is better than not releasing them at all.

However, this brings up some more problems. When the Finalizer is called has
Dispose already been called? When Dispose is called explicitly you can still
call methods on the object, so you could call methods that use resources
that are already disposed. A .NET object could have references to other .NET
objects that could hold resources, so it makes sense to dispose them too, or
does it?

The framework has a pattern which is used by Components. It works like this:
a class implements a protected version of Dispose (not a member of
IDisposable) which is a protected member of the class. This version has a
boolean parameter which is false if the method is called by the Finalizer.
The C# destructor should call this method with false and Dispose will then
only release unmanaged resources. The reason for this is because if this
object is being finalised then so will the objects that it has a reference
to. The class should then implement IDisposable.Dis pose to call this method
with true. The protected Dispose method when it gets false as a method
should release both managed and unmanaged resources because there is no
guarantee how long it will be until the object will be finalized.
C# Essentials (O'Reilly) - "Finalizers are class-only
methods". Not sure what "class-only method" means in this
context, but ususally I would assume that to mean it is
static and would only be called once for the life of the
program, and not once for every object of that class. Am
I reading this correctly? Is it just plain wrong? Will
the Finalize method be called once for every object?
The Finalizer is called for each object unless the object calls
GC.SuppressFina lize(this)

Can an object's destructor/finalizer be called explicitly
by your code? Programming C# (O'Reilly) says no on page
80. Yet on MS site
The Finalizer is protected, so you cannot call it outside of the class (or
derived classes).
(http://msdn.microsoft.com/library/default.asp?
url=/library/en-us/dncscol/html/deepc10192000.a sp?
frame=true) they say yes, search for "One simple solution
is to make the finalizer calls explicit" on that page.
Note the date: October 2000, that's while .NET was in beta: in the RTM you
cannot call the destructor (but you can in C++ <g>)
So, lets assume I have a handle to an unmanaged resource
(intentionally vague), where exactly should I put my code
to free/close the handle? In the Finalize() or Dispose()?
The Dispose(bool) method, as I have described above.
As you can see, I have a poor understanding of the proper
way to do this. I have read lots of articles, but cannot
find any that actually look correct to me.


That's OK, it would be more helpful to you if all the articles/books agreed
<g>

Richard
--
my email ev******@zicf.b et is encrypted with ROT13 (www.rot13.org)
Nov 15 '05 #5

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

52
26996
by: Newsnet Customer | last post by:
Hi, Statement 1: "A dynamically created local object will call it's destructor method when it goes out of scope when a procedure returms" Agree. Statement 2: "A dynamically created object will call it's destructor when it is made a target of a delete".
11
10509
by: Stub | last post by:
Please answer my questions below - thanks! 1. Why "Derived constructor" is called but "Derived destructor" not in Case 1 since object B is new'ed from Derived class? 2. Why "Derived destructor" is called in Case 2 since only ~base() becomes "virtual" and ~Derived() is still non-virtual? 3. Does Case 3 show that we don't need any virtual destructor to make ~Derived() called? 4. Is "virtual destructor" needed only for Case 2?
37
4155
by: WittyGuy | last post by:
Hi, I wonder the necessity of constructor and destructor in a Abstract Class? Is it really needed? ? Wg http://www.gotw.ca/resources/clcm.htm for info about ]
11
5288
by: Ken Durden | last post by:
I am in search of a comprehensive methodology of using these two object cleanup approaches to get rid of a number of bugs, unpleasantries, and cleanup-ordering issues we currently have in our 4-month old C#/MC++ .NET project project. I'd like to thank in advance anyone who takes the time to read and/or respond to this message. At a couple points, it may seem like a rant against C# / .NET, but we are pretty firmly stuck with this approach...
35
3307
by: Peter Oliphant | last post by:
I'm programming in VS C++.NET 2005 using cli:/pure syntax. In my code I have a class derived from Form that creates an instance of one of my custom classes via gcnew and stores the pointer in a member. However, I set a breakpoint at the destructor of this instance's class and it was never called!!! I can see how it might not get called at a deterministic time. But NEVER? So, I guess I need to know the rules about destructors. I would...
11
1978
by: AB | last post by:
Hi All, I've got an array of objects, during the execution of the program I'd like to assign a particular object to a certain element in the object array. The sample code's like this... class ClassA { public: ClassA()
23
2589
by: Ben Voigt | last post by:
I have a POD type with a private destructor. There are a whole hierarchy of derived POD types, all meant to be freed using a public member function Destroy in the base class. I get warning C4624. I read the description, decided that it's exactly what I want, and ignored the warning. Now I'm trying to inherit using a template. Instead of "destructor could not be generated because a base class destructor is inaccessible", I now have an...
8
2047
by: gw7rib | last post by:
I've been bitten twice now by the same bug, and so I thought I would draw it to people's attention to try to save others the problems I've had. The bug arises when you copy code from a destructor to use elsewhere. For example, suppose you have a class Note. This class stores some text, as a linked list of lines of text. The destructor runs as follows: Note::~Note() {
7
1995
by: sam | last post by:
Hi, See when i reading a sourcecode of a program, I read that the constructor is ordinary and after that the programmer has written virtual destructor for that constructor . Why we use the virtual destructor whats the use of it? the code is like this: Network(int input,int output); Network(&Network); virtual ~Network();
0
8432
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
8343
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
8856
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
8633
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
4179
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
4347
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
2762
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
1992
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
2
1747
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.