Since the garbage collector does not determine the order in which finalizers are started and does not care about whether your objects are completed out of order.
By the time your finalizer finishes, the GC has already decided that it and every object that it refers to are not available, and therefore all of these child objects will also be assembled. Each of these objects is added to the finalizer queue, but there is no guarantee that the GC will process them in any reasonable order.
This is one of the limitations of what you can do in the finalizer: you must assume that all of your child objects could already be destroyed. The documentation for Object.Finalize calls this explicitly:
Finalizers of two objects are not guaranteed to run in any particular order, even if one object refers to another. That is, if object A has a reference to object B, and both have finalizers, object B may already be completed when the finalizer of object A begins.
source share