![]() |
|
Модераторы: Partizan, gambit |
![]()
|
|
| Idsa |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 2086 Регистрация: 5.12.2006 Где: Томск Репутация: 14 Всего: 62 |
Тип int - значимый тип данных, соответственно и переменные этого типа хранятся в стеке. Меня интересует, каким типом (значимым или ссылочным) является интовый массив, ну и соответственно, где будет хранитсья объект int[] a (в куче или стеке):
int a - значимый int[] a - ? |
|||
|
||||
| Дрон |
|
|||
![]() Java-ненавистник :) ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 3179 Регистрация: 29.12.2002 Где: Санкт-Петербург Репутация: 24 Всего: 93 |
Ссылочный, а следовательно:
1) память под элементы массива выделяется в куче, а не на стеке 2) ему можно присвоить значение null ( int[] a = null; ) ну и к тому же все массивы, являются производными от класса System.Array, хотя и неявно. Это сообщение отредактировал(а) Дрон - 23.1.2007, 23:48 -------------------- Да. Именно так. |
|||
|
||||
| Idsa |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 2086 Регистрация: 5.12.2006 Где: Томск Репутация: 14 Всего: 62 |
Дрон, спасибо.
Это что-то меня ночью вдруг очень заинтересовал этот вопрос, а утром проснулся и понял, что ответ-то очевиден Добавлено @ 04:34 А кстати, корректно ли переводить value type как значимый? А то вон в Троелсене-то вообще переводится "типы, характеризуемые значениями". |
|||
|
||||
| Дрон |
|
|||
![]() Java-ненавистник :) ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 3179 Регистрация: 29.12.2002 Где: Санкт-Петербург Репутация: 24 Всего: 93 |
Вообще слух немного режет, но как правильней -- не знаю. Надо в МСДН на русском поискать. -------------------- Да. Именно так. |
|||
|
||||
| Idsa |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 2086 Регистрация: 5.12.2006 Где: Томск Репутация: 14 Всего: 62 |
В русском MSDN'e используется термин "типы значений". Тоже не очень красиво
|
|||
|
||||
| ivashkanet |
|
|||
![]() Кодю потиху ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 3684 Регистрация: 23.2.2006 Где: Гомель, Беларусь Репутация: 47 Всего: 149 |
||||
|
||||
| anonym |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 147 Регистрация: 27.11.2006 Репутация: 3 Всего: 3 |
А такой вопрос. Структура по идее хранится в стеке. А что если одно из полей структуры будет к примеру массив? Правильно ли я понимаю, что если у нас есть структура
то в стеке хранится значение х, а так же адрес первого элемента массива, хранящегося в куче? |
|||
|
||||
| ivashkanet |
|
|||
![]() Кодю потиху ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 3684 Регистрация: 23.2.2006 Где: Гомель, Беларусь Репутация: 47 Всего: 149 |
||||
|
||||
| Idsa |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 2086 Регистрация: 5.12.2006 Где: Томск Репутация: 14 Всего: 62 |
||||
|
||||
| ivashkanet |
|
|||
![]() Кодю потиху ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 3684 Регистрация: 23.2.2006 Где: Гомель, Беларусь Репутация: 47 Всего: 149 |
Как-нибудь Я тоже так думаю, но утверждать не берусь |
|||
|
||||
| anonym |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 147 Регистрация: 27.11.2006 Репутация: 3 Всего: 3 |
Что-то я не въехал в одну вещь. Прочитал в Троелсене
В главе 2 рассказывалось о том, что в классе System.Object определен метод МеmberwiseClone(). Этот метод используется для специального типа копирования объекта — когда реальное копирование не происходит, а вместо этого создается еще одна ссылка на область оперативной памяти, занимаемую данным объектом. Для такого типа копирования используется специальный термин — «поверхностное копирование» (shallow сору). Пользователи объектов не вызывают метод MemberwiseClone() напрямую — он вызывается автоматически, когда к объектам ссылочного типа применяется оператор назначения (=), то есть одна ссылка начинает указывать на ту же область оперативной памяти, что и другая. Пример из msdn-a.
Тогда, если при выполнении оператора = вызывается данный метод, должны вывестись одинаковые строки. Но выводит 42 и 50. Почему так? |
|||
|
||||
| mr.DUDA |
|
||||||
|
3D-маньяк ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 8244 Регистрация: 27.7.2003 Где: город-герой Минск Репутация: 110 Всего: 232 |
Если есть структура, поле которой - ссылочный тип, то в структуре будет некий адрес, не обязательно совпадающий с адресом первого элемента массива. Первый элемент можно получить из Marshal.UnsafeAddrOfPinnedArrayElement.
Глядя на пример, всё правильно выводит. -------------------- ![]() |
||||||
|
|||||||
| anonym |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 147 Регистрация: 27.11.2006 Репутация: 3 Всего: 3 |
Так если у нас m1 и m2 ссылаются на одну область оперативной памяти, когда меняем m1.age на 50, m2.age тоже должно изменится на 50... Короче так же, как и в простом присваивании m4 = m3... Что я неправильно понимаю?... Это сообщение отредактировал(а) anonym - 30.1.2007, 09:44 |
|||
|
||||
| ivashkanet |
|
||||
![]() Кодю потиху ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 3684 Регистрация: 23.2.2006 Где: Гомель, Беларусь Репутация: 47 Всего: 149 |
Не знаю где ты такое взял, но по моим сведениям МеmberwiseClone() делает копию объекта, но не глубокую (shalllow). Т.е. если у объекта есть поля-ссылки, то там будет только копия ссылки. В отличии от Deep Copy когда создается полная копия дерева объекта.
Пример:
|
||||
|
|||||
| anonym |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 147 Регистрация: 27.11.2006 Репутация: 3 Всего: 3 |
Троелсен жжёт... Троелсен. Э. С# и платформа .NET. Библиотека программиста. — СПб.: Питер, 2004. —796 с. ISBN 5-318-00750-3 страница 212 Короче, из вышесказанного, как я понял, следует, что метод MemberwiseClone() и знак = равноправны только в том случае, если все поля объекта - ссылочные. Правильно я понял? |
|||
|
||||
| ivashkanet |
|
|||
![]() Кодю потиху ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 3684 Регистрация: 23.2.2006 Где: Гомель, Беларусь Репутация: 47 Всего: 149 |
Нет. Только для структурных типов (там по равенству создается новый экземпляр). А для ссылочных "=" --- коприование ссылки на объект |
|||
|
||||
| anonym |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 147 Регистрация: 27.11.2006 Репутация: 3 Всего: 3 |
Я имею ввиду, если мы создали объект какого-то класса, затем присвоили этот объект другому, то при изменении любых полей одного объекта будет меняться и второй. Верно? И если применить метод MemberwiseClone(), то для класса, где все поля ссылочные - скопируются все ссылки (т. е. как при = ), а если есть значимые типы, то для них будет скопировано само значение.
|
|||
|
||||
| EvgenZ |
|
|||
![]() Freedom in me ![]() ![]() Профиль Группа: Участник Сообщений: 407 Регистрация: 3.8.2006 Репутация: нет Всего: 11 |
Всем привет, такой вопрос, как я понял Clone() это метод интерфейса ICloneable, и класс у которого собираюсь сделать Clone() должен наследовать интерфейс ICloneable, но почему привпеденный код работает без наследования? Это правильно или это правильно только для данного примера и в нормальном проекте потерпит фиаско, или даже здесь это неправильно.
-------------------- <удалено администрацией форума> |
|||
|
||||
| ivashkanet |
|
|||
![]() Кодю потиху ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 3684 Регистрация: 23.2.2006 Где: Гомель, Беларусь Репутация: 47 Всего: 149 |
EvgenZ, а в чем проблема? Метод Clone можно вызвать только потому, что он есть
Интерфейсы нужны для того, чтобы классы, которые ничего не знают о классе кроме того, что он реализует (это слово более точно, чем "наследует") конкретный интерфейс, все же могли вызывать методы объявленные в интерфейсе. Откуда, например, MS могло знать о классе "class one". Что не помешало ему создать кучу методов, в которых используется метод Clone() и интерфейса IClonable. Вроде часть технологии ремоутинг очень сильно юзает его |
|||
|
||||
| Idsa |
|
||||||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 2086 Регистрация: 5.12.2006 Где: Томск Репутация: 14 Всего: 62 |
Чтобы обеспечить классу возможность вовращать свою копию, можно реализовать интерфейс ICloneable, которые содержит единственный метод - Clone():
Если наш класс не содержит ссылочных типов данных, то реализация клонирования предельно проста:
Если же в классе есть ссылочные типы данных, то метод MemberwiseClone() вернет их поверхностные копии (тупо скопирует ссылки на те же объекты). В этом случае клонирование нужно выполнять ручками. Реализуем клонирование для твоего класса one. Чтобы облегчить себе жизнь, сначала вызовем MemberwiseClone(), а затем изменим значение для нашего единственного ссылочного типа данных - объекта класса two.
|
||||||
|
|||||||
| EvgenZ |
|
||||
![]() Freedom in me ![]() ![]() Профиль Группа: Участник Сообщений: 407 Регистрация: 3.8.2006 Репутация: нет Всего: 11 |
Т.е. можно не писать
а просто в класе описать интерфейс? И что-то не работает ))) подскажите пожалуйста
Это сообщение отредактировал(а) EvgenZ - 28.2.2007, 22:52 -------------------- <удалено администрацией форума> |
||||
|
|||||
| Idsa |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 2086 Регистрация: 5.12.2006 Где: Томск Репутация: 14 Всего: 62 |
Конечно, можно! Но не нужно
Приведенный код позволяет проверить, реализован ли у класса определенный интерфейс. Подобный подход может быть полезен, например, когда хранишь массив ссылок на различные объекты, используя интерфейсный полиморфизм. Дык вот в этом массиве некоторые объекты могут поддерживать интерфейс, а другие - нет. Если бы мы не реализовали интерфейс, такую проверку сделать было бы нельзя. |
|||
|
||||
| EvgenZ |
|
|||
![]() Freedom in me ![]() ![]() Профиль Группа: Участник Сообщений: 407 Регистрация: 3.8.2006 Репутация: нет Всего: 11 |
Respect! подскажите еще пожалуйста, что не так в последнем примере, почему ссылочное поле "t" продолжает указывать в одно место?
-------------------- <удалено администрацией форума> |
|||
|
||||
| Idsa |
|
||||||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 2086 Регистрация: 5.12.2006 Где: Томск Репутация: 14 Всего: 62 |
Во-первых, строчки
нужно удалить: за нас это сделает Memberwise.Clone(). А поверхностное копирование выполняется из-за того, что не присваивается
Добавим эту строчку, удалим 2 вышеописанные и в итоге получим:
|
||||||
|
|||||||
| EvgenZ |
|
|||
![]() Freedom in me ![]() ![]() Профиль Группа: Участник Сообщений: 407 Регистрация: 3.8.2006 Репутация: нет Всего: 11 |
немогу никак понять, q.t = t; почему = t, что такое t - это локальная переменная почему просто t ... может утро вечера мудренее ))
Добавлено @ 00:26 и если я явно пишу копирование полей не ссылочных, это разве плохо? -------------------- <удалено администрацией форума> |
|||
|
||||
| Idsa |
|
||||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 2086 Регистрация: 5.12.2006 Где: Томск Репутация: 14 Всего: 62 |
Зачем откладывать на утро то, что можно сделать ночью? Сейчас еще раз посмотрел на код и задумался: "А почему он работает?" Правильно, конечно, будет заменить строчку q.t = t на q.getC = t; Добавлено @ 00:48
Это не плохо. Вполне нормально. Только при этом не нужно вызывать MemberwiseClone(), т. к. это бессмысленно. Добавлено @ 00:58
Пытаюсь разобраться... При клонировании мы в классе one создаем объект o типа one. При этом нам доступны private-члены этого объекта... Может, это такая фишка, чтобы упростить клонирование? Это сообщение отредактировал(а) Idsa - 1.3.2007, 01:13 |
||||
|
|||||
| EvgenZ |
|
|||
![]() Freedom in me ![]() ![]() Профиль Группа: Участник Сообщений: 407 Регистрация: 3.8.2006 Репутация: нет Всего: 11 |
А t разве не локальная переменная?
ихихих кажется понял, сам себя запутал, зато длагодаря этому вроде понял, как это работает! Это сообщение отредактировал(а) EvgenZ - 1.3.2007, 11:24 -------------------- <удалено администрацией форума> |
|||
|
||||
| Naum |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 743 Регистрация: 7.9.2005 Где: Саратов, ул. Поса дского, 298 Репутация: 8 Всего: 15 |
Если в классе C объявлен приватный член M. То у любых экземпляров класса C, созданных в методах класса C, член M будет видимым. Грубо говоря, если человек знает свое строение, то он знает строение любого другого человека. Однако он не знает строение, например, собаки, пока не разрежет ее, или по нашему не взломает. )) -------------------- У нас всего два праздника Новый год и ТЯПница. |
|||
|
||||
| Idsa |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 2086 Регистрация: 5.12.2006 Где: Томск Репутация: 14 Всего: 62 |
Naum, +1. Спасибо, буду знать. В некоторых ситуациях это действительно может помочь при клонировании. Например, если у нас есть private член, для которого не определено public-свойства (но при этом он используется в каком-либо методе), то без этой фишки не обойтись. Это сообщение отредактировал(а) Idsa - 3.4.2009, 13:20 |
|||
|
||||
| Madrid |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 97 Регистрация: 27.5.2006 Репутация: нет Всего: нет |
Всем привет!Прочитав ваш разговор у меня возник вопрос.
Переменные значимого типа располагаются в стеке! А переменные ссылочного типа в куче! 1)
т.е. переменные значимого типа могут располагаться в куче? 2) А переменные ссылочного типа могут располагаться в стеке?(К примеру структурная переменая, одним из членов которой является переменная ссылочного типа). |
|||
|
||||
| Idsa |
|
||||||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 2086 Регистрация: 5.12.2006 Где: Томск Репутация: 14 Всего: 62 |
Это действительно так. Проверить это достаточно просто. Как известно, все значимые типы данных должны наследоваться от класса ValueType. Однако, как гласит MSDN:
, Array является прямым неследником Object.
Да, конечно. Помимо описанного способа хранения значимых данных в куче через массив, не стоит забывать про boxing/unboxing, когда мы можем при необходимости хранения объекта значимого типа данных в куче (или наоборот) сделать, например, вот так:
Да и вообще, возвращаясь к вопросу, могут ли переменные значимого типа храниться в куче, стоит вспомнить, что объекты классов, которые, в частности, содержат значимые типы данных, хранятся в куче. Это сообщение отредактировал(а) Idsa - 2.3.2007, 01:19 |
||||||
|
|||||||
| ivashkanet |
|
|||
![]() Кодю потиху ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 3684 Регистрация: 23.2.2006 Где: Гомель, Беларусь Репутация: 47 Всего: 149 |
Да. Есть такая операция как запаковка (boxing). Или распаковка Нет. От ссылочного типа в стеке хранится только ссылка (4 байта) на объект в куче |
|||
|
||||
| Madrid |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 97 Регистрация: 27.5.2006 Репутация: нет Всего: нет |
Спасибо!
|
|||
|
||||
| kurzon |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 307 Регистрация: 12.8.2007 Репутация: -8 Всего: -11 |
А приметивніе типы ето какие типы?
|
|||
|
||||
| thomas |
|
|||
![]() Доцент... почти ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1385 Регистрация: 3.10.2006 Где: " Сказочное королевство" Репутация: 6 Всего: 65 |
kurzon,
"C# 2005 для профессионалов" стр. 82 "Типы значений и ссылочные типы". -------------------- Крепко жму горло, искренне ваш Thomas. (С)vingrad Некоторые сорта флоры буквально за одно мгновение превращают нас в фауну! Проблемы негров шерифа не волнуют. |
|||
|
||||
| ivashkanet |
|
||||
![]() Кодю потиху ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 3684 Регистрация: 23.2.2006 Где: Гомель, Беларусь Репутация: 47 Всего: 149 |
Гугль в руки
Добавлено через 1 минуту и 51 секунду Еще там же:
Т.е. можно сказать, что это все что подсвечивается синим в редакторе |
||||
|
|||||
| thomas |
|
|||
![]() Доцент... почти ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1385 Регистрация: 3.10.2006 Где: " Сказочное королевство" Репутация: 6 Всего: 65 |
ivashkanet,
-------------------- Крепко жму горло, искренне ваш Thomas. (С)vingrad Некоторые сорта флоры буквально за одно мгновение превращают нас в фауну! Проблемы негров шерифа не волнуют. |
|||
|
||||
| ivashkanet |
|
|||
![]() Кодю потиху ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 3684 Регистрация: 23.2.2006 Где: Гомель, Беларусь Репутация: 47 Всего: 149 |
thomas,
|
|||
|
||||
![]()
|
| Прежде чем создать тему, посмотрите сюда: | |
|
|
Используйте теги [code=csharp][/code] для подсветки кода. Используйтe чекбокс "транслит" если у Вас нет русских шрифтов. Что делать если Вам помогли, но отблагодарить помощника плюсом в репутацию Вы не можете(не хватает сообщений)? Пишите сюда, или отправляйте репорт. Поставим :) Так же не забывайте отмечать свой вопрос решенным, если он таковым является :) Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, mr.DUDA, THandle. |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | Общие вопросы по .NET и C# | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |