Здравствуйте! Вот такой вопрос, подскажите - расскажите, вот смотрите, т.е в C# все классы наследуются от базового класса Object (у нас есть наследование), то почему тогда можно наследоваться еще от одного класса?
если мы ничего явно не указываем - мы наследуем базовый Object. Если мы указываем какой-то класс - мы наследуем именно его (а он уже в свою очередь наследует базовый Object)
но если к примеры мы откроем mscorlib.dll и найдем там скажем тип Int32 то там не указано, что он наследуется от Object или я чего то не понимаю? Где посмотреть что любой тип наследует Object или это наследование получается во время выполнения?
и еще к примеру, структуры как говорят наследуются от класса ValueType, но ведь структура не может наследоваться от класса? Или в какой момент это происходит?
Дмитрий:
Int32, как и прочие примитивные типы - структуры, которые наследуются от ValueType. ValueType в свою очередь уже наследует Object. В рантайме все что не наследуется от ValueType попадает в кучу (тут уже в зависимости от размера - LOH или SOH), все остальное - в стек.
ayazer: Что значит наследуется от ValueType? ValueType - class, а Int32 - struct, как может struct наследоваться от class? Я понимаю что ValueType является базовым типом для Int32 и в книжках это понаписано, но меня интересует в какой момент ValueType становится базовым типом для Int32, и аналогично в какой момент Object становится базовым типом для ValueObject, это происходит во время компиляции, компилятором?
на самом деле в с# структуры ОБЯЗАНЫ быть унаследованы от класса.
Явный признак - наличие базовых .GetType() / .ToString() / etc у всяких енумов (которые наследуются от Enum, которые наследуется от ValueType, которые наследуется от Object, который содержит эти методы). И именно потому что они УЖЕ ОБЯЗАНЫ наследовать класс - нельзя унаследовать структуру от произвольного класса. Т.е. то что пользователь не может унаследовать структуру от класса НЕ ОЗНАЧАЕТ что на самом деле структура не наследует класс. Ключевое слово struct фактически и означает наследование от ValueType.
Плюс ко всему, ValueType - вообще исключительный случай как для компилятора, так и для CLR. Фактически, наследование от ValueType говорит что это объект фиксированного размера, потому его можно засунуть в кучу.
Дмитрий: просто вас сбивает само понятие структура. Например в C++ struct и class это одно и тоже(разница в видимости членов по умолчанию). Тут также, фактически struct это sealed class и при этом говорит компилятору, что память выделять на стеке.
Роман: да, такое упрощение наверно действительно будет гараздо проще понять.
и чуть больше подробностей:
и "класс" и "структура" - это просто абстракции придуманные человеком для человека. Просто под "структурой" подразумевается сущность неизменяемой длинны (в отличии от "класса", чья длина может меняться), которая скорее всего будет хранится в стеке (детальней ниже), для которой нужно сгенерировать класс-обертку (для боксинга/анбоксинга в случае передачи по ссылке). И возможно я забыл про еще что-то. Потому в данном случае наследование от ValueType это в первую очередь флаг что "вот этот кусок кода надо трактовать немного иначе чем обычно"
по поводу хранения структур в стеке - да, действительно так написано почти во всех книгах + так действительно будет почти всегда. НО в каком-то блоге проскакивало сообщение от одного с разработчиков, который описал почему это не совсем правда. если коротко, то
1) value-тайпы не *обязаны* а *могут* хранится в стеке. Точно об этом станет известно *только* в рантайме
2) это вообще не прописано в стандарте, потому эта логика может меняться в зависимости от компилятора и среды выполнения
3) value-тайпы которые объявленны в теле анонимных/лямбда методов один фиг попадают в кучу
ayazer: согласен, но по поводу 2, среды всего 2, .net и mono, а там это так. Или читал или видел видео с конференции, но класс можно разместить на стеке, а значимый тип в куче без проблем.
Дмитрий: и после того как рихтерер будет прочитан раза 3 (с перерывами по года пол на практику), можно начинать"Nick Harrison, Chris Farrel - Under the hood of .net memory management" + некоторые главы с "Sasha Goldshtein, Dima Zurbalev, Ido Flatow - Pro .NET Performance". Оно конечно частично устарело уже, но понимая принципы догнать проблем не будет. Если хочется еще глубже - "Serge Lidin - Expert .net 2.0 IL Assembler" + спецификации самого CLI (как минимум для предидущей книги нужно под рукой иметь 3юю часть спецификаций с IL командами). Это если говорить чисто за .нет (и не трогая всякие asp.net mvc/winforms/wpf)
ayazer: "с перерывами на практику" - просто взять какой то проект и реализовывать в свободное время? Или как лучше сделать, чтобы знания из Рихтера совместить с практикой?
Дмитрий: ну... а я и не говорил что рихтера не хватит чтоб начать работать =) Но то что его нужно будет несколько раз перечитать - это правда.
"взять проект и реализовывать в свободное время" - плохой подход, такое обычно ничего хорошим не заканчивается. надо взять проект и НАЙТИ время чтоб его реализовать. на диких велосипедах, собрав кучу костылей и наступив на все возможные грабли. А потом прочитать книги и понять как нужно было делать на самом деле. И переписать нормально. Или для максимума усвояемости - отрефакторить убив в 2 раза больше времени чем нужно было бы чтоб переписать. И повторять пока не выйдет найти работу. Само-собой задачи каждый раз усложнять и добавлять какую-то новую технологию. Как раз к моменту получения оффера будет рихтер (возможно несколько раз) + что-то по мс склю (при всей моей любви к постгресу, с .нетом чаще используют ms sql) + что-то (скорее всего) по mvc (которое за собой потянет еще кучу специфичных для веба вещей).