Q:

Why garbage collector takes objects in the wrong order?

I have an application with two classes, A and B. The class A has inside a reference to class B. The destructors of the classes do some cleanup of resources but they have to be called in the right order, first the destructor of A and then the destructor of B. 
What is happening is that somehow the destructor of B is called first and then the destructor of A is crashing because is trying to execute methods from a disposed object.
Is this behavior of the GC correct? I expected the GC to detect that A has a reference to B and then call the A destructor first. Am I right?
Thanks mates!
PD: In case of doubt about destructor/finalizer/disposer etc that's what we have:
~A()
{
    this.Dispose();
}

~B()
{
    this.Dispose();
}    

A:

As others have noted, your finalizers are wrong, wrong, wrong. You cannot simply call Dispose in a finalizer and expect good things to happen. Read up on the correct way to implement the disposable pattern.
Getting that right is the beginning, not the end, of the work you have to do. In addition to all the other correct answers here, I note that:

the finalizer can (and usually does) run on a different thread. Finalizing resources that have an affinity to a particular thread is dangerous, you can run into deadlocks if you are not careful, and so on.
finalization can "resurrect" a dead object by assigning a reference to it to a variable that is in a live object. Do not do that. It is incredibly confusing.
finalizers can run on objects that were partially constructed when a thread abort exception happened. You cannot assume that any invariant that is true of a fully-constructed object is true of an object being finalized.

Writing a finalizer correctly is extremely difficult for all these reasons. Avoid, avoid, avoid. 

A:

The GC is nondeterministic: it is not guaranteed to garbage-collect your objects in any particular order, or at any time, or even ever---it could decide to keep them around after your program is completed, if it wanted to. Thus finalizers are very rarely useful or used.
If you want deterministic finalization, you should use the IDisposable pattern.

A:

From http://msdn.microsoft.com/en-us/magazine/bb985010.aspx:

The runtime doesn't make any guarantees as to the order in which Finalize methods are called. For example, let's say there is an object that contains a pointer to an inner object. The garbage collector has detected that both objects are garbage. Furthermore, say that the inner object's Finalize method gets called first. Now, the outer object's Finalize method is allowed to access the inner object and call methods on it, but the inner object has been finalized and the results may be unpredictable. For this reason, it is strongly recommended that Finalize methods not access any inner, member objects.

