Section 10.13, Destructors, of the C# Language Specification 3.0 states the following:
Destructors are not inherited. Thus, a class has no destructors other than the one which may be declared in that class.
The Destructors section of the C# Programming Guide contains an example demonstrating how destructors in an inheritance hierarchy are called, including the following statement:
...the destructors for the ... classes are called automatically, and in order, from the most-derived to the least-derived.
I have investigated this with various practical examples, including one with a base class that defines a destructor, with a derived class that inherits from the base class and does not define a destructor. Creating an instance of the derived class, allowing all references to the instance to go out of scope and then forcing a garbage collection demonstrates that the destructor defined in the base class is called when the instance of the derived class is finalized.
My question is what does "destructors are not inherited" actually mean, since although you can't call a destructor explicitly, destructors in an inheritance chain are called automatically, and base class destructors are called even if the derived class does not define a destructor?
Does it relate to some subtle semantic distinction that finalization is implemented by the garbage collector rather than the C# language/compiler?
Edit 1:
While the C# language spec also states that "instance constructors are not inherited", the behaviour in relation to constructors is significantly different from desctructors, and fits better IMO with the "not inherited" terminology, as demonstrated in the example below:
public class ConstructorTestBase
{
public ConstructorTestBase(string exampleParam)
{
}
}
public class ConstructorTest: ConstructorTestBase
{
public ConstructorTest(int testParam)
: base(string.Empty)
{
}
}
...
// The following is valid since there is a derived class constructor defined that
// accepts an integer parmameter.
ConstructorTest test1 = new ConstructorTest(5);
// The following is not valid since the base class constructor is not inherited
// by the derived class and the derived class does not define a constructor that
// takes a string parameter.
ConstructorTest test2 = new ConstructorTest("Test");
The behaviour in relation to destructors is very different from this, as demonstrated in the following example, which extends the previous constructor example by adding a desctructor only to the base class.
public class ConstructorTestBase
{
public ConstructorTestBase(string exampleParam)
{
}
~ConstructorTestBase()
{
Console.WriteLine("~ConstructorTestBase()");
}
}
...
ConstructorTest test1 = new ConstructorTest(5);
test1 = null;
GC.Collect();
The example above demonstrates that base class constructors will be called when an instance of a derived class is finalized, even if the derived class does not explicitly define a destructor.
My point is simply that I have encountered many people who do not realise or understand that this what happens, and a significant part of the reason for this is the "destructors are not inherited" statement.
Edit 2:
The C# language spec also states the following and gives a code example of the under-the-hood implementation:
Destructors are implemented by overriding the virtual method Finalize on System.Object. C# programs are not permitted to override this method or call it (or overrides of it) directly.
Since the under-the-hood implementation is, in fact, based on inheritance, as stated above, I think my question is valid and I don't think any of the responses I've received so far have addressed the question properly - What does "destructors are not inherited" actually mean?