8 / 9 / 1
Регистрация: 21.08.2012
Сообщений: 34
|
||||||
1 | ||||||
Value type и reference type19.02.2013, 13:53. Показов 11311. Ответов 29
Метки нет (Все метки)
Всем привет!
После прочтения некоторых книг по .NET до сих пор меня мучат несколько вопросов. В некоторых книгах, говоря про отличие типов значения от ссылочных типов, утверждается, что основное их отличие - это то, что типы значения хранятся в стеке. Ссылочные типы так: сама ссылка в стеке и ссылается на область памяти в куче. Но что будет, если у нас такой код:
Так как массив - это ссылочный тип, то получается, что 10 элементов типа int хранятся все-таки в куче. Я правильно понимаю? А как хранятся элементы value типа в коллекциях, например, в List? Тоже ведь в куче? А в List<T> например? И последнее. В приведенном выше коде будет производится операция упаковки, или она производится только в том случае, когда требуется приведение к типу object? Извините за сумбурность, просто много вопросов накопилось, на которые разные книги дают противоречивые ответы. Заранее благодраю за ответы.
0
|
19.02.2013, 13:53 | |
Ответы с готовыми решениями:
29
Особенности хранения value type и reference type Интересная ситуация с reference type Ошибка в программе: The non-generic type 'ArrayList' cannot be used with type arguments Ошибка CDO:Unable to cast COM object of type 'System.__ComObject' to interface type 'Microsoft.Office.Interop.Outlook.MailItem' |
17688 / 12873 / 3366
Регистрация: 17.09.2011
Сообщений: 21,138
|
|
19.02.2013, 17:11 | 2 |
Плохие это книги.
Основное отличие в том, что при присваивании переменной и передачи между методами value типы копируются полностью, а ссылочные типы - только ссылка. Да. Точно так же, потому что лист в кишках использует обычный массив. Второй вариант.
0
|
136 / 138 / 18
Регистрация: 26.07.2010
Сообщений: 911
|
||||||
19.02.2013, 17:27 | 3 | |||||
Упаковки не будет, хотя ваши структуры и будут хранится в куче.
Упаковки не будет так же и тогда, когда вы инициализируете поле класса которое является структурой. Хотя поле вашего класса тоже будет хранится в куче.
Интерфейсная переменная всегда является ссылочным типом.
0
|
8 / 9 / 1
Регистрация: 21.08.2012
Сообщений: 34
|
|
19.02.2013, 18:02 [ТС] | 4 |
Всем спасибо большое за ответы. Все для себя прояснил.
0
|
Темная сторона .Net
592 / 489 / 39
Регистрация: 21.07.2012
Сообщений: 1,668
|
|||||||||||
19.02.2013, 18:44 | 5 | ||||||||||
Fmamedov, Упаковка\распаковка - это миграция из стека в кучу и наоборот.
Например
0
|
17688 / 12873 / 3366
Регистрация: 17.09.2011
Сообщений: 21,138
|
|
19.02.2013, 20:59 | 6 |
Не обязательно.
Вообще стек/куча - это детали реализации, не стоит на них зацикливаться. Единственное, что нужно знать - это то, что при боксинге происходит копирование. Вот основное знание.
0
|
136 / 138 / 18
Регистрация: 26.07.2010
Сообщений: 911
|
|
19.02.2013, 21:07 | 7 |
Ну, как мы с вами выяснили недавно, то копирование происходит всегда, я думаю гораздо важнее, так это то, что после боксинга объект так просто не удалится => останется в памяти.
Т.е. расход ресурсов а при упаковке еще и производительности.
0
|
17688 / 12873 / 3366
Регистрация: 17.09.2011
Сообщений: 21,138
|
|
19.02.2013, 21:19 | 8 |
При передаче/присваивании - да.
А при боксинге еще и при вызове методов и именно этот момент является основным для понимания. В неуправляемой среде - да, это было бы действительно важно. В случае же с CLR, где памятью заведует довольно эффективный сборщик, подобные моменты уходят на второй план. Собственно, именно для этого сборщик и сделали. Расход там настолько незначительный, что даже не стоит о нем запариваться. По крайней мере, я пока еще не встречал ситуации, в которой боксинг оказывал бы сколь-нибудь значительное влияние на расход ресурсов (не встречал - не значит, конечно же, что таких ситуаций нет). Если же структура у вас размером больше 16-и байт, то стоит серьезно задуматься о том, чтобы сделать ее классом.
0
|
Темная сторона .Net
592 / 489 / 39
Регистрация: 21.07.2012
Сообщений: 1,668
|
|
19.02.2013, 21:23 | 9 |
это подтверждается тем,что в куче могут быть свои стеки,правильно?
Где-то генерал Липперт писал такое)
0
|
17688 / 12873 / 3366
Регистрация: 17.09.2011
Сообщений: 21,138
|
|
19.02.2013, 21:53 | 10 |
Не совсем.
Деталь реализации (Implementation detail) - это функционал, не являющийся обязательством со стороны разработчика платформы (майкрософта) перед конечными пользователями (разработчиками ПО): он может эту деталь изменять по своему усмотрению от версии к версии, не уведомляя разработчиков и не предоставляя документацию по этим моментам. То есть это - не контракт и не стоит приложение строить таким образом, чтобы оно зависело от этих деталей. Ну это примерно как обнаружить в платформе баг, эксплуатация которого дает вам как пользователю какие-то бонусы или обходные пути, и строить логику своего приложения вокруг эксплуатации этого бага. Баг в следующей версии платформы пофиксят и ваше приложение станет бесполезным. Если вы, например, возьмете официальную документацию - спецификацию языка С#, то не увидите в довольно точном документе слов о том, что-де структуры выделяются в стеке тогда-то, а в куче - тогда-то. Только весьма обтекаемые фразы в стиле "структуры, будучи значимыми типами, не требуют выделения памяти в куче" или "обычно память под структуру выделяется в стеке". Другими словами, спецификация языка не обязывает того, кто будет писать реализацию этого языка (компилятор, например, или порт фреймворка под линупс/макось) выделять память под структуры строго в определенном месте. Другое дело оператор stackalloc для выделения памяти именно в стеке - там все строго, ибо это - контракт, то есть обязательство перед разработчиками ПО, что данный оператор имеет конкретный функционал. Значит вокруг этого оператора можно строить логику приложения - его поведение будет кочевать из версии к версии или по крайней мере информация о любых изменниях, касающихся его работы, будет предоставлена заранее. Как-то так.
1
|
Темная сторона .Net
592 / 489 / 39
Регистрация: 21.07.2012
Сообщений: 1,668
|
|
19.02.2013, 22:05 | 11 |
0
|
17688 / 12873 / 3366
Регистрация: 17.09.2011
Сообщений: 21,138
|
|
19.02.2013, 23:05 | 12 |
0
|
136 / 138 / 18
Регистрация: 26.07.2010
Сообщений: 911
|
|
20.02.2013, 16:15 | 13 |
Я не понял этого предложения
Ну, это если вы все ссылки уберете. Потому что был скорее всего представлен как единичная операция.
0
|
1 / 1 / 0
Регистрация: 12.01.2010
Сообщений: 18
|
|
18.07.2013, 00:29 | 14 |
0
|
17688 / 12873 / 3366
Регистрация: 17.09.2011
Сообщений: 21,138
|
||||||
18.07.2013, 02:17 | 15 | |||||
В приведенном автором коде? С чего это вдруг?
Там показана визуализация расположения в памяти локальных переменных и их значений. А вопрос был про массивы. Вот этот код:
1
|
1 / 1 / 0
Регистрация: 12.01.2010
Сообщений: 18
|
|
18.07.2013, 09:26 | 16 |
Вы правы, упаковок не происходит. Разобрался наконец.
0
|
101 / 101 / 15
Регистрация: 23.05.2012
Сообщений: 260
|
|||||||||||||||||||||||||||||||
18.07.2013, 13:49 | 17 | ||||||||||||||||||||||||||||||
Вот и меня заинтересовали.
А какая блин разница? Пол форума про упаковки распаковки стеки кучи значения ссылки.... Мы что на разделе ассемблера??? Или есть какой-то подводный айсберг с которым я не сталкивался? и который может существенно испортить жизнь? Мне пока удавалось не заморачиваться на это и обойтись такой логикой: Си это же Си!! ?? С++: есть 2 варианта объявления переменной (да и объекта)
А далее динамическое выделение памяти, то есть то которое хрен знает сколько было возможно с помощью
С# решили долой -> * & ^ все будет
"классы" суть ссылки (->) Следствие int a,b; a=b//копируется значение "class" A,B A=B//копируется ссылка т.е. "ptrA=ptrB" т.е. адреc Вот и вопрос что я такого упустил и нафиг себе мозг засорять ненужной информацией
0
|
17688 / 12873 / 3366
Регистрация: 17.09.2011
Сообщений: 21,138
|
|
18.07.2013, 17:41 | 18 |
1. При неосторожном использовании структур можно довольно серьезно просадить производительность именно из-за постоянных распаковок/запаковок.
2. Не зная ситуаций, когда происходит перепаковка и/или не зная последствий перепаковки, можно провести долгие ночи с отладчиком, пытаясь понять, почему вот тут значение вроде как изменяется, а когда использую переменную вот тут — оно старое. 3. Людям просто нравится этот язык и платформа и они интересуются тем, как там внутри все устроено. Вполне нормальное желание для увлекающегося человека, как мне кажется. Самое смешное, что в C# всё это есть, кроме последнего (если не считать оператора XOR).
0
|
101 / 101 / 15
Регистрация: 23.05.2012
Сообщений: 260
|
||||||
18.07.2013, 18:45 | 19 | |||||
Вот если забыть что все эти int'ы и doubl'ы структуры (а они та и есть те самые значимые) слово struct последний раз использовал 1000 лет назад. Все что хоть проще самого простого все равно class. Дабы в С# (не замарачиваясь на вот ЭТИ тонкости) выглядят они ну пипец одинаково. Более того один черт ты конструкторик какой никакой да пару методов-свойств... да и припишешь.
Вот а я о чем. Терминов по вводили... мама дорогая кучи фигучи управляемая а что если неуправляемая... КАПЕЦ!!! А суть то вся таже. НЕТ классам в памяти приложения (бишь стеке), ВСЕ И ВСЯ (за исключением...) в динамическую память. И ввели единый синтаксис для ВСЕГО. Бесспорно небезопасный код суть С++, но вопрос если есть С++ на...зачем лесть куда не надо. С++ - это мегаХРЕНЬ. А С# офигенно упрощенно шикарный и, что не мало важно, оставшийся таки сверхфункциональным язык. созданный для прикаладного ПО. Или кто-то там драйвера и операционки на нем пишет? Я с появлением С# еще присматривался, но после VS2003 (и появления в С++ ^ от .NET до кучи ко всему прежнему) послал этот С++ к бабушке на... холодец. Оно вещь конечно хорошая но все эти префиксы так грузят и грязнят код а С# - красота да и только: прост читабелен элегантен РЕЗЮМЕ по п.2: Вот терминов много а суть одна: "экземпляр класса" хранит адрес и его если что и копирует (последствия... да изменяется все везде т.к. объект та один) "экземпляр структуры" суть значение его (значение) и копирует (последствия... новая переменная новый объект в памяти со своим значением (пусть какое-то время и совпадающим)) А при передаче в методы... ну так там всегда копия создавалась пока пальцем (* или ref) не ткнешь что его-его родного... ну а вот здесь та как с тобой не согласиться. Интересующийся... ДА. CLR дабы покорчить из себя DirectX (не судите за аналогию прослойку между железом наплодившимся и ПипецМегаСообществом программистов, интересующихся, студентов-школяров, отнефигделающих, и вообще 2 пыца и фотоальботмчик гуманитариев которым и язык та знать не надо а мал-мал да таки по прикольней PowerPointa что-нибудь да замутят) вообще много чего породил и "кучи" и "некучи". А суть та таже осталась "динамическая" и "и хрен там было размер массива по ходу поменять 10 значит 10 или const int n=10". Но вот "молодежь" понаслышав ЭТО ВСЕ лезет туда где норовит офигеть взорвать себе мозг а потом не по делу кучами интересоваться и при ошибках в структуре программы упаковки городить. Хотя я думаю ты согласишься что проблемы такого рода естественно бывают но ох редко дюже. Сомневаюсь что кто-то в программа будет путем
Все что надо знать В метод - копия (если прямо иного не сказано) Из List'а достал - он же. Накидывайтесь
0
|
Master of Orion
|
|
18.07.2013, 19:49 | 20 |
DPW, один из самых частоиспользуемых компонентов CLR - итераторы (которые создаются каждый раз при вызове foreach, linq-запроса и пр) - являются мутабельными структурами. Оп-па, видимо авторы .Net не знали, что
0
|
18.07.2013, 19:49 | |
18.07.2013, 19:49 | |
Помогаю со студенческими работами здесь
20
Предполагается ли в C# синтаксис для создания переменной того типа, который указан в переменной Type type Cannot access a nonstatic member of outer type 'ClassLibrary1.Form1' via nested type 'ClassLibrary1.Form1.Spr' Циклическая ссылка (A circular reference was detected while serializing an object of type 'tblProduct') The ViewData item that has the key 'TownDepart.TownName' is of type 'System.String' but must be of type 'IEnum Warning: The type 'lala' conflicts with the imported type... Реализовать метод string[] Method(Type type), который будет выводить все члены, видимые вне сборки, помеченные атрибута Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |