Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why the destructors in that instance’s inheritance chain are called, in order, from most derived to least derived?

Tags:

c#

Base on the C# specification, 10.13 Destructors

" When an instance is destructed, the destructors in that instance’s inheritance chain are called, in order, from most derived to least derived."

My questions are:

why destructors are called, in order, from most derived to least derived? why not are called, in order, from least derived to most derived or other order?

like image 976
jacky_shen Avatar asked Sep 29 '12 07:09

jacky_shen


2 Answers

Presumably, it's because the derived class has knowledge of the base class's members, and might need to use them in the destructor. If the base constructor is called first, the members might be unavailable, or the object's state might otherwise have been put in an invalid state by the base destructor.

The base class, of course, has no knowledge of or ability to access the members of its derived classes, so the problem is avoided by calling the more derived destructor first.

like image 125
phoog Avatar answered Oct 23 '22 18:10

phoog


Because objects are built up from the least derived to the most derived, so they have to be torn down from the most derived to the lest derived.

The deriving class knows about base class, but the base class doesn't know about the derived class. If you would tear down the object from the least derived class to the most derived class, the base class would remove things that the derived class might need in the process.

Consider for example that the base class has a list of objects:

public class MyBase {

  public List<SomeObject> list;

  public MyBase(){
    list = new List<SomeObject>();
    list.Add(new SomeObject());
    list.Add(new SomeObject());
    list.Add(new SomeObject());
  }

  ~MyBase() {
    foreach (SomeObject obj in list) {
      obj.Cleanup();
    }
    list.Clear();
  }

}

The derived class adds something to each item in the list:

public class MyDerived : MyBase {

  public MyDerived() {
    foreach (SomeObject obj in list) {
      obj.SomeProperty = new Handler();
    }
  }

  ~MyDerived(){
    foreach (SomeObject obj in list) {
      obj.SomeProperty.Cleanup();
    }
  }

}

When the object is torn down, the derived class needs access to the list in order to clean up what it added. If the base class was destructed first, the derived class wouldn't have access to the objects in the list.

(Note however that IDisposable is normally a better option to handle controlled cleanup of objects.)

like image 20
Guffa Avatar answered Oct 23 '22 18:10

Guffa