В разных сборках могут быть одинаковые пространства имен, открыв один такой namespace, будут доступны типы из разных сборок
При исполнении программы у каждого потока есть свой стек, его размер - 1МБ В процессе выполнения программы в этот стек помещаются разлиные значения переменных и полей, например при вызове метода T1:
public int T()
{
var v = "q";
T1(v);
return 1;
}
private void T1(string q)
{
Console.WriteLine(q);
}
В стеке находятся: ...
- переменная v
- аргумент метода T1 q
- адрес возврата из функции T1 в функцию T
тем самым, когда мы выходим из метода T1 стек становится таким: ...
- переменная v
Все записи относящиеся к методу T1 из стека извлекаются
Это происходит в стеке, в куче же создаются ссылочные типы и выделяется память под их экземпляры. При первом обращении к типу,нужно создать его представление в куче, таблицу методов, по которой можно определить все методы, которые декларирует тип. Два обязательных элемента у каждого жителя кучи - индекс синхронизации(нужен CLR) и указать на тип. Указатель на тип нужен для определения типов у экземпляров объектов, например у экземпляра класса Employee, будет ссылка на тип Employee(это тоже объект в куче), самое интересное, что у Employee тоже существует ссылка на на объект типа - это тип Type, а у типа Type эта ссылка указывает на самого себя.Также кроме таблицы методов в типе будут находиться все статические члены типа, потому что они определяеются только один раз. Все типы загружаются в момент надобности(обращения к ним), отследить загрузку можно поставиви break point в статическом ctor'e.
Все экзмпляры хранятся в куче, выделяя место для своих полей(нестатических), причем CLR изначально инициализирует все поля значениями по умолчанию, и уже после вызова конструктора они инициализируются, вызов конструтора возвращает указатель на расположение объекта в памяти.
Также нужно отметить, что вызовы виртуальных/невиртуальных и статических методов в среде CLR различаются, при вызове статических и невиртуальных методов CLR смотрит тип объекта и находит метод в таблице методов объекта типа(если не нашел там, то просмотрит базовый тип объекта, ссылка на него также хранится в куче, далее, при необходимости JIT компилятор преобразует CLR код в машинные команды, и выполняет их
В случае виртуального метода все сложнее, дело в том, что он может быть переопределен в наследнике, поэтому CLR необходимо знать реальный тип объекта, а не декларируемый, поэтому он обращается к переменной на которой вызывается метод, находит его тип, а после этого начинает искать в таблице методов вызываемый метод
В случае невиртуального метода происходит поиск по декларируемому типу переменной, для этого типа происходит поиск по таблице методов, выбирается нужный и вызывается(или JIT компилятор)
Кстати вызов метода GetType возвращает указатель на тип объекта, тип объекта в системе создается лишь один раз => вызов метода GetType на разных экземплярах одного типа возвращает тот же самый объект