Вопрос, достойный настоящего профана, но он меня мучает.

Пусть есть два класса:

public class B {public int a;}
public class D : B {public int b;}


И следующий код, использующий их:

B b = new D();
D d = (D)b;


Собственно, как я это вижу.
1) new выделяет память под объект D, будем учитывать для простоты только память, выделенную для полей классов. Т.е. под класс D выделится память объемом 4*2 = 8 байт - под поле класса и под поле класса-родителя. Итак, new возвращает ссылку на объект данного класса в памяти.
2) Далее происходит приведение типа к типу-родителю, т.е. к B. Класс B знать не знает, что у него есть потомок, у которого есть еще одно поле. Для объекта класса B нужно 4 байта памяти, а не 8. Куда деваются остальные байты? Какой на самом деле тип имеет переменная b?
3) Далее мы явно приводим b к типу D. И снова та же непонятка (для меня) с количеством выделяемой памяти. Откуда возьмутся еще 4 байта на новое поле? Что вообще происходит?

Пример кода взят из книги Рихтера. Его объяснение я не понимаю, прошу помощи.