:: Не фоксом единым
Re: Узнать, упакована ли переменная
Simple777

Сообщений: 33855
Дата регистрации: 05.11.2006
Принцип Питера в действии:

"В иерархической системе каждый поднимается до уровня своей некомпетентности. Со временем все должности займут некомпетентные сотрудники". [sm128]
Ratings: 0 negative/0 positive
Re: Узнать, упакована ли переменная
S-type
Автор

Сообщений: 2969
Дата регистрации: 24.04.2004
S-type
Вопрос - при вызове

Console.WriteLine(((A)o).f);

что изменится, если структуру заменить на класс?

Ответ - операции упаковки не будет. Т.е. нехрен использовать структуры, которые потом надо упаковывать - сразу надо использовать классы.
Ratings: 0 negative/0 positive
Re: Узнать, упакована ли переменная
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
Когда выбирают что сделать - структуру или класс, то думают прежде всего о логической стороне дела - будет это "значение" (пускай и хитрое, состоящее из нескольких компонент), или это будет "объект" который изменяется, реагирует на внешние сигналы...
struct вообще достаточно нечасто применяется. Как раз по причине того что это "значение", а в большинстве случаев в их качестве выступают встроенные типы - те же int, string... Структуру по-хорошему нельзя изменять после создания/начального заполнения. Т.е. её можно заменить "полностью" - ну как число, было 1234 стало 5678. А не "частично", типа вторую цифру заменить с 2 на 9 - это как раз нарушает "смысл" числа - если тебе нужно такое, то вероятно тебе нужно было сразу НЕ число (как что-то единое), а "набор цифр"

P.S. Это я к тому что про упаковки/распаковки в это время вообще не думают. Про них можно вспомнить при оптимизации кода, а не во время проектирования классов...

P.P.S. Ну вопросы на собеседовании в принципе не могут быть "умными". Что можно спросить то у претендента, кроме какой-то из страниц "азбуки". Попросить написать программу? Это уже НЕ собеседование. Рассказать как он крут и чем занимался - можно, но это обычно есть в резюме, зачем повторяться...


------------------
WBR, Igor




Исправлено 2 раз(а). Последнее : Igor Korolyov, 15.04.17 19:03
Ratings: 0 negative/0 positive
Re: Узнать, упакована ли переменная
Simple777

Сообщений: 33855
Дата регистрации: 05.11.2006
Ну, степень лояльности к работодателю можно узнать без проблем во время собеседования. С компетентностью, конечно, посложнее будет.
Ratings: 0 negative/0 positive
Re: Узнать, упакована ли переменная
S-type
Автор

Сообщений: 2969
Дата регистрации: 24.04.2004
Igor Korolyov
P.S. Это я к тому что про упаковки/распаковки в это время вообще не думают.

Это точно.

Igor Korolyov
Про них можно вспомнить при оптимизации кода, а не во время проектирования классов...
Честно говоря, сомневаюсь, что упаковка/распаковка может сильно повлиять на производительность.
Ratings: 0 negative/0 positive
Re: Узнать, упакована ли переменная
S-type
Автор

Сообщений: 2969
Дата регистрации: 24.04.2004
Igor Korolyov
Т.е. если видим object - то там всегда будет либо экземпляр ссылочного типа, либо упакованное значение "значного" типа. "Неупакованным" будет значение в переменной типа value type.
Вероятно ты не уловил того момента, что после object o = val; в o будет вовсе не "упакованная переменная val" - в ней будет КОПИЯ ЗНАЧЕНИЯ этой переменной, упакованная дабы хранится в переменной ссылочного типа... Никакой связи с val уже не будет...

Почитал на разных сайтах определение и родил:

Преобразование значения переменной значимого типа в значение переменной ссылочного типа сопровождается неявной операцией упаковки (boxing) — помещение копии значения из значимого типа в класс-обёртку (экземпляр которого сохраняется в куче). Тип класса-обёртки (используемого для упаковки) генерируется CLR и реализует интерфейсы сохраняемого значимого типа.

Преобразование значения переменной ссылочного типа в значение переменной значимого типа вызывает операцию распаковки (unboxing) — извлечение из класса-обёртки значения и помещения копии значения в переменную (располагающуюся в стеке) значимого типа.

Так всё корректно?
Ratings: 0 negative/0 positive
Re: Узнать, упакована ли переменная
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
Да, вроде как корректно...
S-type
сомневаюсь, что упаковка/распаковка может сильно повлиять на производительность
Во многих случаях влияет - не зазря же придумали generic-и. Одной из основных целей как раз и было дать возможность использовать коллекции структур БЕЗ операций упаковки/распаковки оных (для reference типов тоже есть свои плюсы в типизированной коллекции) - как происходит в не-generic ArrayList и им подобных. Вторая основная цель - добавление typesafety, т.е. контроля типов коллекциям.


------------------
WBR, Igor
Ratings: 0 negative/0 positive
Re: Узнать, упакована ли переменная
S-type
Автор

Сообщений: 2969
Дата регистрации: 24.04.2004
В "CLR via C#. Программирование на платформе Microsoft .NET Framework 4.5 на языке C#. 4-е изд. (2013)" сказано (подчёркнуто мной):

Дж. Рихтер
Для преобразования значимого типа в ссылочный служит упаковка (boxing).
При упаковке экземпляра значимого типа происходит следующее.

    1. В управляемой куче выделяется память. Ее объем определяется длиной значимого типа и двумя дополнительными членами — указателем на типовой объект и индексом блока синхронизации. Эти члены необходимы для всех объектов в управляемой куче.
    2. Поля значимого типа копируются в память, только что выделенную в куче.
    3. Возвращается адрес объекта. Этот адрес является ссылкой на объект, то есть значимый тип превращается в ссылочный.


Компилятор C# создает IL-код, необходимый для упаковки экземпляра значимого типа, автоматически, но вы должны понимать, что происходит «за кулисами» и помнить об опасности «распухания» кода и снижения производительности.

С одной стороны, явно про класс-обёртку не упомянуто. С другой стороны, из написанного видно, что в этом классе есть поле, указывающее на тип переменной значимого типа.

Фраза про "опасность «распухания» кода" - наверное, имеется ввиду IL-код.



Исправлено 2 раз(а). Последнее : S-type, 16.04.17 13:40
Ratings: 0 negative/0 positive
Re: Узнать, упакована ли переменная
S-type
Автор

Сообщений: 2969
Дата регистрации: 24.04.2004
Igor Korolyov
S-type
сомневаюсь, что упаковка/распаковка может сильно повлиять на производительность
Во многих случаях влияет - не зазря же придумали generic-и.
Мне казалось, что обобщения придуманы для "повторного использования" кода... Как-то даже и не задумывался, что обобщённая коллекция будет приводить к уменьшению количества упаковок. Хотя, если задуматься - так оно и есть.
Ratings: 0 negative/0 positive
Re: Узнать, упакована ли переменная
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
S-type
С одной стороны, явно про класс-обёртку не упомянуто.
Что есть класс-обёртка в твоей терминологии?

Внутренне, на самом примитивном уровне, любой экземпляр (т.е. объект) ссылочного типа в памяти (в куче) хранится именно в таком виде - dword с номером синхроблока, потом dword указатель на type, потом собственно "поля" этого объекта. При том адресуется экземпляр чуть хитрее - адресом 2-го поля, т.е. "указателя на тип", а первое поле получается как указатель_на_объект-4 (это если ты будешь в отладчике в memory окне смотреть на хранение объектов в памяти, и получать "адрес объекта" через &переменная).
Соответственно если прописать в блоке памяти в куче эти 2 служебных поля и потом поместить собственно "значимые поля из value type", то мы и получим по сути экземпляр ссылочного типа - вероятно его можно назвать объектом-обёрткой (классом называть экземпляр некорректно). Вот то куда указывает 2-е поле - это указатель на класс (или тип - это слова-синонимы). Только я не уверен что существует два разных "класса" для того же Int32 - один для использования с "обычными значениями на стеке", и другой для "упакованных" значений в куче...

S-type
С другой стороны, из написанного видно, что в этом классе есть поле, указывающее на тип переменной значимого типа.
Нет, это поле указывает на СОБСТВЕННО "тип". Не на переменную, не на экземпляр. Если грубо - это указатель на System.Type, связанный с данным объектом. Олег как раз задавал вопрос "неужели с каждым значением система хранит и его тип" - так вот для reference типов это так и есть. И для упакованных value типов тоже. Для неупакованных - только у компилятора есть информация о типе, которой он и пользуется при генерации кода. В рантайме уже нет никакой "ссылки на тип" - но она, естественно, появится при "упаковке" (т.к. сама инструкция box требует не только "значения" но и "типа" в качестве "параметров").

Кстати, забавный нюанс - в некоторых случаях C# компилятор вставляет инструкцию box даже для reference типов (в generic классах где параметр типа "ограничен" ссылочными типами) - при jit-компиляции таких box-инги просто игнорируются. Т.е. далеко не всякий встретившийся в IL box будет на самом деле исполнен процессором

S-type
обобщения придуманы для "повторного использования" кода
Это всё слишком общие слова. "Повторно использовать код" можно вполне себе и без generic-ов. В версиях до 1.1 только так и можно было работать, и ничего - работали же
Из мануала:
Цитата:
by using a generic type parameter T you can write a single class that other client code can use without incurring the cost or risk of runtime casts or boxing operations
Т.е. основная цель - это устранение потенциального "несоответствия типов" в рантайме (т.к. без generic придётся использовать именно object в качестве типа - а значит в тот же ArrayList можно напихать и строки и числа и Customer-ов и Product-ы, и потом бодро падать при попытке преобразовать элемент списка обратно к "логически требуемому" типу - например к Customer) ну и "упаковки" для значных типов - это уже вопрос производительности и использования памяти.
Конечно же и в "старом" фреймворке можно было обеспечить типобезопасность коллекции - НО это потребовало бы создания своего класса-наследника, в котором и "проверялись" бы типы при работе с коллекцией - сам же интерфейс был бы типобезопасным - но не "стандартным" IList, а, скажем IListString. И вот тут то как раз попытка "сделать правильно" и приводила бы к многократному дублированию кода - т.к. в ArrayListString нельзя помещать числа, а в ArrayListInt нельзя помещать даты ну и т.д.
Т.е. избыточность в данном случае возникает на сама по себе, а лишь от попыток написать типобезопасный код. Если забить на всё и оперировать штатным ArrayList, просто ловя периодически InvalidCastException, то избыточности никакой не возникнет. Возникнет лишь "проблема фокса" с мешаниной типов


------------------
WBR, Igor
Ratings: 0 negative/0 positive
Re: Узнать, упакована ли переменная
of63

Сообщений: 25256
Откуда: Н.Новгород
Дата регистрации: 13.02.2008
Дурацкий вопрос, если можно:int val = 5;
int val = 5;
object o = val; // упаковка

становится видна "переменная" под именем o:
- и занимается память под значение val?, значение-то и его тип компилятор знает,
- пакует (что это за преобразование? символьную строку - "зазипует" что ли?)
- int j = (int)o - значит тип запакованного теряется при паковке. надо знать его заранее, тобы паспаковать?
Ratings: 0 negative/0 positive
Re: Узнать, упакована ли переменная
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
of63
Дурацкий вопрос...
Да, создаётся переменная o, способная содержать в себе ссылку на что угодно (т.к. тип переменной это object - базовый для любых объектов в среде дотнета).
Для переменной val в момент её создания выделяется память в стеке, туда записывается "просто значение 5".
Упаковка, это создание объекта-обёртки для типа int. Объект такого типа (как и любого другого "значного" типа) может быть представлен в 2-х видах - в неупакованном - в стеке или внутри других сложных объектов (если у них есть поля соответствующего типа), и в "упакованном" - обычно в "куче". Грубо говоря, это хранение соответствующего значения "с заголовками" - такими же как у любых других объектов среды. По сути упаковка это выделение памяти, установление значений в "служебных" полях (счётчик блокировок и указатель на тип) и копирование данных в собственно поля с данными (которые находятся сразу же за 2-мя служебными полями).
Тип данных как раз не теряется при упаковке - напротив, он "появляется" в явном виде - как поле в соответствующей структуре в памяти. Вот для "неупакованных" значений тип явно не хранится - его знает компилятор и соответствующим образом генерирует код.


------------------
WBR, Igor
Ratings: 0 negative/0 positive
Re: Узнать, упакована ли переменная
of63

Сообщений: 25256
Откуда: Н.Новгород
Дата регистрации: 13.02.2008
("Стек" - наверное, в данном ответе - это "свалка памяти". "Стек" - слово заставляет контролировать, что мол, если втолкнули туда, та надо и в том же порядке и извлечь)

счётчик блокировок и указатель на тип - еще 2 понятия... Это что за звери... Такое только в фоксе возможно... Да... Шарп - не мое)



Исправлено 1 раз(а). Последнее : of63, 16.04.17 23:37
Ratings: 0 negative/0 positive
Re: Узнать, упакована ли переменная
S-type
Автор

Сообщений: 2969
Дата регистрации: 24.04.2004
Igor Korolyov
S-type
С одной стороны, явно про класс-обёртку не упомянуто.
Что есть класс-обёртка в твоей терминологии?
В общем то, на авторсто термина не претендую - подсмотрел на каком то сайте. Но, термин мне понравился, как отражающи суть. Поясню.

На сколько понимаю, ссылка должна быть на объект, а объект - это экземпляр какого то класса. Класс нужен для операции "упаковка", причём под упаковкой понимается не сжатие (как во фразе "файл упакован утилитой ZIP"), а "помещение куда то внутрь" (как во фразе "турист упаковал снаряжение" или "в магазине тщательно упаковали покупку"). В принципе, можно было написать просто "класс", или даже просто "упаковка". Но, мне кажется, "класс-обёртка" всё таки понятнее, чем "класс-упаковка".

Igor Korolyov
Внутренне, на самом примитивном уровне, любой экземпляр (т.е. объект) ссылочного типа в памяти (в куче) хранится именно в таком виде - dword с номером синхроблока, потом dword указатель на type, потом собственно "поля" этого объекта. При том адресуется экземпляр чуть хитрее - адресом 2-го поля, т.е. "указателя на тип", а первое поле получается как указатель_на_объект-4 (это если ты будешь в отладчике в memory окне смотреть на хранение объектов в памяти, и получать "адрес объекта" через &переменная).
Мне кажется, это уже слишком глубоко... Вряд ли эти значния могут пригодиться при написании программы на C#.

Или, ты хочешь сказать, что определение, данное Рихтером, совпадает с определением самого обычного объекта?

Igor Korolyov
Соответственно если прописать в блоке памяти в куче эти 2 служебных поля и потом поместить собственно "значимые поля из value type", то мы и получим по сути экземпляр ссылочного типа - вероятно его можно назвать объектом-обёрткой (классом называть экземпляр некорректно). Вот то куда указывает 2-е поле - это указатель на класс (или тип - это слова-синонимы). Только я не уверен что существует два разных "класса" для того же Int32 - один для использования с "обычными значениями на стеке", и другой для "упакованных" значений в куче...
Опять мозг взорван Да, CLR создаёт в памяти объект. Но разьве объект это (по определению) не экземпляр класса? Разьве может быть "просто" объект?


Igor Korolyov
S-type
С другой стороны, из написанного видно, что в этом классе есть поле, указывающее на тип переменной значимого типа.
Нет, это поле указывает на СОБСТВЕННО "тип". Не на переменную, не на экземпляр.
Собственно, это же и написал... Можно написать так:

> в этом классе есть поле, указывающее на тип (переменной значимого типа).

Или так:

> в этом классе есть поле, ссылающееся на тип (который был у переменной значимого типа).

Igor Korolyov
Т.е. основная цель - это устранение потенциального "несоответствия типов" в рантайме (т.к. без generic придётся использовать именно object в качестве типа - а значит в тот же ArrayList можно напихать и строки и числа и Customer-ов и Product-ы, и потом бодро падать при попытке преобразовать элемент списка обратно к "логически требуемому" типу - например к Customer) ну и "упаковки" для значных типов - это уже вопрос производительности и использования памяти.
Конечно же и в "старом" фреймворке можно было обеспечить типобезопасность коллекции - НО это потребовало бы создания своего класса-наследника, в котором и "проверялись" бы типы при работе с коллекцией - сам же интерфейс был бы типобезопасным - но не "стандартным" IList, а, скажем IListString. И вот тут то как раз попытка "сделать правильно" и приводила бы к многократному дублированию кода - т.к. в ArrayListString нельзя помещать числа, а в ArrayListInt нельзя помещать даты ну и т.д.
Т.е. избыточность в данном случае возникает на сама по себе, а лишь от попыток написать типобезопасный код. Если забить на всё и оперировать штатным ArrayList, просто ловя периодически InvalidCastException, то избыточности никакой не возникнет.
Не могу не согласиться.

Igor Korolyov
Возникнет лишь "проблема фокса" с мешаниной типов
Мы живём в постФокс-овском мире...
Ratings: 0 negative/0 positive
Re: Узнать, упакована ли переменная
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
S-type
На сколько понимаю, ссылка должна быть на объект, а объект - это экземпляр какого то класса. Класс нужен для операции "упаковка"
Оно то да, только я сильно не уверен что это ОТДЕЛЬНЫЙ класс. Т.е. что Int32 и "упакованный в виде экземпляра Int32" это два разных класса. И потому сомневаюсь что корректно применять термин класс-обёртка.
Вот хранятся они по разному - упакованный и неупакованный int. А что класс у них один (но в первом случае он "явно" не привязан к значению, хотя для вызовов методов наверняка используется) - это скорее всего так и есть.
S-type
Или, ты хочешь сказать, что определение, данное Рихтером, совпадает с определением самого обычного объекта?
Да, упакованный value-тип это "самый обычный объект".
S-type
Но разьве объект это (по определению) не экземпляр класса? Разьве может быть "просто" объект?
Не понял вопроса... Объект это экземпляр (instance) определённого класса (тип более общее понятие нежели класс). В документации иногда и конкретные значения value-типов называют instance, но мне кажется это не совсем точно и приводит к путанице.

S-type
Собственно, это же и написал... Можно написать так:
Тут слово "переменная" лишнее - оно не существенно. Значение value-типа ("экземпляр", если уж нарушать терминологию) может существовать и без переменной - например как поле в другом типе, или как элемент в массиве...


------------------
WBR, Igor
Ratings: 0 negative/0 positive
Re: Узнать, упакована ли переменная
S-type
Автор

Сообщений: 2969
Дата регистрации: 24.04.2004
Igor Korolyov
только я сильно не уверен что это ОТДЕЛЬНЫЙ класс. Т.е. что Int32 и "упакованный в виде экземпляра Int32" это два разных класса. И потому сомневаюсь что корректно применять термин класс-обёртка.
Вот хранятся они по разному - упакованный и неупакованный int. А что класс у них один (но в первом случае он "явно" не привязан к значению, хотя для вызовов методов наверняка используется) - это скорее всего так и есть.
Если так подумать... Если для упакованного Int32 в поле "ссылка на тип" хранится ссылка на "Int32", значит это ссылочная переменная с типом "Int32"

Это напоминает JavaScript. На некоторых сайтах по JavaScript упоминаются "классы-оболочки примитивных типов". Может, будет корректно говорить не обёртка, а оболочка? Хотя, по англицки "wrapper" - "обертка, упаковка"...

Igor Korolyov
Тут слово "переменная" лишнее - оно не существенно. Значение value-типа ("экземпляр", если уж нарушать терминологию) может существовать и без переменной - например как поле в другом типе, или как элемент в массиве...

Вот, новая формулировка с учётом замечаний:

Преобразование значения переменной значимого типа в значение переменной ссылочного типа сопровождается неявной операцией упаковки (boxing) — помещение копии значения из значимого типа в объект-обёртку (который сохраняется в куче).

Преобразование значения переменной ссылочного типа в значение переменной значимого типа вызывает операцию распаковки (unboxing) — извлечение из объекта-обёртки значения и помещения копии значения в переменную (которая располагается в стеке) значимого типа.

Теперь то точно придраться (в хорошем смысле этого слова) не к чему?
Ratings: 0 negative/0 positive
Re: Узнать, упакована ли переменная
Simple777

Сообщений: 33855
Дата регистрации: 05.11.2006
S-type
Теперь то точно придраться (в хорошем смысле этого слова) не к чему?

Ну, ежели ТС непременно настаивает на "придирании", то по правилам следует писать "Теперь-то", то бишь через дефис. [sm128]
Ratings: 0 negative/0 positive
Re: Узнать, упакована ли переменная
S-type
Автор

Сообщений: 2969
Дата регистрации: 24.04.2004
Simple777
Ну, ежели ТС непременно настаивает на "придирании", то по правилам следует писать "Теперь-то", то бишь через дефис. [sm128]

По поводу русского. Вчера сын пришёл с пробника по русскому, жаловался - что дают всякие ненужные слова. И тут я узнал, что всю жизнь говорил неправильно - надо говорить жерлО. Т.е. правильно будет "жерлО вулкана". Какя жуть...

Давно уже говорю всем - надо каждые 100 лет приводить письменный язык в соответсвие с разговорным. А то соЛнце, леГко - какое то говнище...
Ratings: 0 negative/0 positive
Re: Узнать, упакована ли переменная
Simple777

Сообщений: 33855
Дата регистрации: 05.11.2006
Орфоэпический словарь сообщает, что жЕрло - устаревшая форма ударения. Стало быть, во времена Пушкина таки было жЕрло. [sm128]
Ratings: 0 negative/0 positive
Re: Узнать, упакована ли переменная
S-type
Автор

Сообщений: 2969
Дата регистрации: 24.04.2004
На ebooks.grsu.by сказано:

Цитата:
Устаревшие слова принято классифицировать на историзмы и архаизмы. Историзмы – это слова, обозначающие реалии прошедших эпох. Сюда относятся наименования явлений общественно-политической жизни (опричник, крепостной, эсер), названия административных, учебных учреждений, организаций (земство, прогимназия, бурса), названия лиц по должности, роду занятий (городничий, голова, стряпчий, унтер), наименования предметов быта, блюд, средств передвижения (камзол, взвар «напиток», конка «трамвай»), названия мер длины, веса, денежных единиц (сажень, верста, фунт, гривенник).
Архаизмы ( от греч. archaios – древний) – устаревшие слова, имеющие в современном языке синонимы (ланиты – щёки, чело - лоб). Архаизмы делятся на лексические и семантические. Среди первых, в свою очередь, выделяются:
а) собственно лексические – слова, устаревшие целиком, как звуковые комплексы (десница - правая рука, ветрило – парус);
б) лексико –фонетические – отличающиеся от современных лишь несколькими звуками (конфекты – конфеты, пиит – поэт). Среди них особый подвид составляют лексико-акцентологические архаизмы – слова, изменившие ударение (ножн,ы – н,ожны, муз,ыка – м,узыка).
в) лексико-словообразовательные — слова, отличающиеся от современных аффиксальными морфемами ( рыбарь – рыбак, супротив – напротив);
г) грамматические архаизмы – слова, употреблённые в устаревших грамматических формах (И на покорную рояль властительно ложились руки (А.Блок). Здесь существительное рояль – женского рода, о чём свидетельствует форма согласуемого с ним имени прилагательного. Таковой была родовая принадлежность данного существительного в начале ХХ века)
Семантические архаизмы – устаревшие значения существующих в активном словаре слов ( позор «зрелище» – позор «бесчестье», живот «жизнь» – живот «часть тела»).

Язык постоянно меняется. То, что слова меняют ударение - абсолютно не критично для смысла.
Ratings: 0 negative/0 positive


Извините, только зарегистрированные пользователи могут оставлять сообщения в этом форуме.

On-line: 16 tata  (Гостей: 15)

© 2000-2024 Fox Club 
Яндекс.Метрика