#c_sharp
Например, у меня есть базовый класс А и наследующийся от него класс B. A objA = new B(); Создав объект objA, какого же все-таки типа я получаю объект? Хранятся ли где-то в памяти указатели на все родительские классы?
Ответы
Ответ 1
Если у вас A и B — классы (то есть, ссылочные типы), следует различать между compile-time (заявленным) типом ссылки и runtime- (фактическим) типом. Заявленный тип — A, и на этапе компиляции вы по этой ссылке можете пользоваться лишь операциями, доступными в классе A. А фактический тип — B (и это легко проверить, определив виртуальную функцию в A и перекрыв её в B). Ссылка в C# может ссылаться на любой объект типа, совместимого по присваиванию с типом ссылки. Например, если A — класс, то объект производного типа. Если A — интерфейс, то объект типа, имплементирующего интерфейс. (Интерфейсы в C# не являются классами.) Если A = object, то (упакованные) типы-значения наподобие int. Как именно хранятся в памяти объекты, вам не должно быть интересно: это не оговаривается стандартом (как и само наличие стека и кучи, например). Вам должны быть важны только семантика присваивания и тождества: если вы присваиваете одной ссылке другую, они ссылаются на один и тот же объект, и изменения в этом объекте видны по обеим ссылкам. Тождественными считаются ссылки, ссылающиеся на один и тот же объект (для проверки нужно использовать object.ReferenceEquals). А если А — структура (то есть, тип-значение), то от неё вовсе нельзя наследоваться. Для структур при присваивании вы получаете копию структуры, и изменения в одной не влияют на изменения в другой. Тождественными считаются структуры с одинаковыми полями. Разные два экземпляра такой структуры не отличимы (так же как вы не отличаете два «экземпляра» числа 5, например).Ответ 2
С оговоркой на текущую реализацию CLR и предполагая что под классом вы подразумевали именно класс: После выполнения вашего кода вы получите: Экземпляр класса B, лежащий в куче. Адрес этого экземпляра, лежащий в локальной переменной objA. Внутри экзепляра класса лежит системное поле TypeHandle, которое указывает на таблицу методов (MethodTable) типа (класса B), которому принаджежит экземпляр. Внутри MethodTable есть ссылка на метаданные о собственно типе B (полях, свойствах, методах и прочем) - EEClass. В EEClass класса B есть ссылка на EEClass родительского типа - класса A. В целом получается примерно так: Картинка взята из MSDN: Внутреннее устройство .NET Framework — как CLR создает объекты периода выполнения - статья чуть битая, картинки подгружаются по клику.Ответ 3
Если A - reference type, то вы получаете ссылку, которая ссылается на некоторый объект в хипе. Объект этот имеет тип B, с ним лежит ссылка на объект его типа (который тоже где-то в хипе). Если A - value type, то вы получаете ссылку objA на объект в стеке. У Рихтера в "CLR via C#" об этом хорошо описано. "Chapter 4 Type Fundamentals, How Things Relate at Runtime ", стр. 105
Комментариев нет:
Отправить комментарий