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

Сообщений: 2969
Дата регистрации: 24.04.2004
Есть код:

int val = 5;
object o = val; // упаковка
int j = (int)o; // распаковка

Есть какая то функция, что бы можно было увидеть - упакована переменная, или нет?

int val = 5;
object o = val; // упаковка
Console.WriteLine(что_то(o)); // True
int j = (int)o; // распаковка
Console.WriteLine(что_то(j)); // False

Или, непосредственно из языка это нельзя сделать, и надо IL код смотреть?



Исправлено 1 раз(а). Последнее : S-type, 10.04.17 16:15
Ratings: 0 negative/0 positive
Re: Узнать, упакована ли переменная
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
Упаковывается не "переменная" а значение. Значение "значного типа" (структура, перечисление - в общем любой value type) для помещения в переменную "ссылочного типа" (любой reference type). Ну и плюс к тому приведение к типам интерфейсов (они по идее тоже ссылочные типы).

Т.е. если видим object - то там всегда будет либо экземпляр ссылочного типа, либо упакованное значение "значного" типа. "Неупакованным" будет значение в переменной типа value type.

Вероятно ты не уловил того момента, что после object o = val; в o будет вовсе не "упакованная переменная val" - в ней будет КОПИЯ ЗНАЧЕНИЯ этой переменной, упакованная дабы хранится в переменной ссылочного типа... Никакой связи с val уже не будет...


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

Сообщений: 2969
Дата регистрации: 24.04.2004
Как известно, при распаковке необходимо указывать точно такой же тип, что был при упаковке. Так, если сделать:

int i = 5;
object o = i;
long j = (long)o; // так нельзя !
//long j = (int)o; // так можно

произойдёт исключение InvalidCastException.

Igor Korolyov
Упаковывается не "переменная" а значение.

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

Сообщений: 2969
Дата регистрации: 24.04.2004
Igor Korolyov
Упаковывается не "переменная" а значение.
Полностью согласен.... Исправлюсь... [sm016]


Igor Korolyov
Т.е. если видим object - то там всегда будет либо экземпляр ссылочного типа, либо упакованное значение "значного" типа.

И, как то можно отличить, что это экземпляр ссылочного типа или это упакованное значение значимого типа?

Зайду с другого конца. Можно как то отследить событие "упаковка"? Или, это только смотреть IL код?



Исправлено 1 раз(а). Последнее : S-type, 10.04.17 18:10
Ratings: 0 negative/0 positive
Re: Узнать, упакована ли переменная
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
Конечно. В нете любое значение имеет тип
И тот же GetType() его покажет. А т.к. этот метод определён у System.Object, то смотреть его можно для совершенно любой переменной (т.к. тип переменной и тип хранящегося в ней значения вовсе не обязаны совпадать).
Предвосхищая другой вопрос - как определить "тип переменной" - я не знаю прямого способа, возможно что его и не существует. Т.к. на самом деле в процессе компиляции такая сущность как "переменная" может вообще исчезнуть - останется лишь "значение" - т.е. ссылка на объект или данные valuetype на вершине стека исполнения, а "хранилище" под него создано не будет.
Для "параметров методов" и "полей типа" тип можно определить через рефлексию. Т.к. эти сущности тоже вполне могут хранить вовсе не то что прописано в их названии...
P.S. нет, я не думаю что можно отследить "событие упаковка". Да и не вижу в этом никакого смысла - в рантайме (из самой работающей программы) определять произошло такое или нет. А в отладочных целях - вероятно профилировщики/отладчики могут это отслеживать, т.к. IL команда box конечно же есть Это если цель стоит в оптимизации кода - поиске "узких мест"... Хотя как правило идут не от "возможных причин" а собственно от факта - есть тормоза в том или ином методе - ищут что же там тормозит


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




Исправлено 1 раз(а). Последнее : Igor Korolyov, 10.04.17 18:43
Ratings: 0 negative/0 positive
Re: Узнать, упакована ли переменная
of63

Сообщений: 25256
Откуда: Н.Новгород
Дата регистрации: 13.02.2008
(Чуть-чуть, и каждую переменную в Си можно превратить в структуру {char тип, собственно_переменная}, и получится язык без явной типизации ?)
Ratings: 0 negative/0 positive
Re: Узнать, упакована ли переменная
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
Не переменную а её значение... Миллион переменных вполне может ссылаться на один и тот же объект. Ну по сути так оно и есть - каждое значение имеет так или иначе связанный с ним тип. Либо явно, либо неявно - но это доступно для языка независимо от того, в каком виде это значение находится - в упакованном или нет...
"Типизация" ведь относится к процессу компиляции - чтобы в переменную типа "строка" не пытались записать число - напрямую, без ЯВНЫХ разрешений на то от кодера. Совсем не для того чтобы "усложнить жизнь" это придумано.


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

Сообщений: 2969
Дата регистрации: 24.04.2004
Igor Korolyov
Кт.к. тип переменной и тип хранящегося в ней значения вовсе не обязаны совпадать

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

Сообщений: 34580
Дата регистрации: 28.05.2002
object some = new Person()
Переменная имеет тип object - хранит объект типа Person() - т.к. object имеется (в любом случае, для любых типов) в иерархии наследования.
Аналогично с переменными типа интерфейс - правда там тип переменной не в иерархии наследования для типа объекта должен быть, а в списке реализуемых интерфейсов.


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

Сообщений: 25256
Откуда: Н.Новгород
Дата регистрации: 13.02.2008
Си не хранит не имени, не типа, переменной. Это же изначально чисто ассемблер ( для отдельно взятого процессора). Я его и называю ассемблером, ну, плюс "фреймверк" от разработчиков MS (.NET, он же "дотнет")
Ratings: 0 negative/0 positive
Re: Узнать, упакована ли переменная
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
Если ты про C/C++, то насколько я знаю напрямую он не хранит "типы" - но из vtable (точнее из указателя на оную в соответствующем поле структуры составляющей "экземпляр класса") опосредованно можно получить информацию о том что же это за класс такой (не его имя или ещё что из исходника - хотя в pdb файле есть вся информация для связывания "адреса" с "именем метода" - отладчик как раз всё найдёт). Для "простых типов", конечно, никакой vtable не будет - там тупо блок памяти и его интерпретация (деление на поля, если там они есть вообще, если это не "просто число" или "просто строка") целиком и полностью управляется компилятором и в рантайме невозможна (как невозможно указать для void* на что же он указывает - адрес и адрес - интерпретация целиком от кода зависит).
Если про C#, то там любой reference объект имеет весьма сложную структуру - в частности там есть поле TypeHandle со ссылкой на структуру MethodTable, которая по сути и есть "тип" (там всё на порядок сложнее, конечно - одних разнообразных структур с два десятка будет - и всё это описывает "тип").
Для value типов, как я понимаю, всё чуть проще - вызовы методов разрешаются на этапе компиляции, запись и чтение "значения" происходит напрямую. НО для них ведь есть операция упаковки, тот самый box. Который из "просто пары байт в стеке" создаёт полноценный объект, со всеми его причиндалами...
"Имя типа" на самом деле вторично - первичен его идентификатор - то что позволяет впоследствии получить и имя, и адреса методов и метаданные reflection позволяющие "расшифровать" все те байтики что записаны в "теле объекта", разложив их по его "полям".
В общем то это тот же с++ только гораздо более сложный по внутреннему устройству - но гораздо проще для прикладного разработчика.

Машинного ассемблера в C# нет - есть IL код - это этакий платформенно-независимый "ассемблер", и jit-компилятор, который из IL кода уже динамически создаёт машинный код - под текущую платформу, учитывая массу всяких факторов, которые недоступны обычному ассемблеру или даже компилятору языка с/с++ (т.к. машинный ассемблер равно как и си-компилятор работают на машине программиста, выдавая "статический" машинный код, а jit работает непосредственно у пользователя - позволяя "подстроить" создаваемый код под его машину)
Банально - на ассемблере или в с/с++ невозможно создать код работающий и в x86 и в x64 режимах. В дотнете (C# или любой другой язык под эту систему) это штатная возможность - т.к. у разработчика создаётся только IL код, а в x86 или в x64 машинные коды он превращается уже у пользователя.
Полагаю что и jitting в ARM или какую IBM-овскую z-архитектуру был бы вполне возможен (теоретически) - практически же этого нет, т.к. не портируется всё прочее - грубо говоря инфраструктура дотнета адекватно работает пока только на Win-платформе Но проекты типа mono, или последние движения самой MS в плане разделения мега-системы дотнета на более мелкие части - выделение так называемого Core - вполне могут привести и к тому что написанный и откомпилированный в винде код запустится и на мобильном телефоне, и на IBM-овском мэйнфрейме
В конце концов "идеологически" дотнет это та же java, только производства MS - а java работает практически везде - от встроенного ПО "умного ночного горшка" до суперкомпьютерных кластеров.


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

Сообщений: 25256
Откуда: Н.Новгород
Дата регистрации: 13.02.2008
мда... но тем не менее, есть нормальные проги...
типа

>"В конце концов "идеологически" дотнет это та же java, только производства MS - а java работает практически везде "
Игорь, Игорь... Может быть, и ява - может оказаться как фокс)
Ratings: 0 negative/0 positive
Re: Узнать, упакована ли переменная
S-type
Автор

Сообщений: 2969
Дата регистрации: 24.04.2004
Порылся в нете. Везде, при обсуждении подобных вопросов, приводится IL код. Например, на ru.stackoverflow.com приведён вопрос

Цитата:
Есть запакованная структура, как изменить значение поля структуры, при этом не распаковывая её?

и ответ на него:

Цитата:
Через интерфейс

Пример кода:

interface I
{
void Inc();
}
// структура, о которой идёт речь
struct A : I
{
public int f;
public void Inc()
{
f++;
}
}
void Main()
{
var o = (I)new A(); // упаковка структуры
(o).Inc(); // изменение данных в упакованной структуре без распаковки
(o).Dump(); // что то не понятное...
}

и, в качестве доказательства "в IL-коде нету unbox".

Вопрос - при вызове

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

произойдёт распаковка? И, что изменится, если структуру заменить на класс?

Если нельзя определить, из C#, что произошла распаковка, наверное придётся научиться получать IL-код и разбираться в нём



Исправлено 1 раз(а). Последнее : S-type, 11.04.17 10:02
Ratings: 0 negative/0 positive
Re: Узнать, упакована ли переменная
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
S-type
Если нельзя определить, из C#, что произошла распаковка...
То наверное это попросту НЕ НУЖНО в практической работе


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

Сообщений: 2969
Дата регистрации: 24.04.2004
Igor Korolyov
То наверное это попросту НЕ НУЖНО в практической работе

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

Сообщений: 2969
Дата регистрации: 24.04.2004
На ru.stackoverflow.com приведён кусок IL кода. В нём видно, что

(o).Dump();

компилируется в

IL_0018: call LINQPad.Extensions.Dump

Скачал LINQPad. С его помощью смотреть IL код очень даже просто - достаточно нажать одну кнопку:

[attachment 27419 s1_.png]
Ratings: 0 negative/0 positive
Re: Узнать, упакована ли переменная
S-type
Автор

Сообщений: 2969
Дата регистрации: 24.04.2004
Igor Korolyov
То наверное это попросту НЕ НУЖНО в практической работе
В работе, может, и не нужно. Но, как показала практика, на собеседовании любят задавать разные дурацкие вопросы про упаковку/распаковку, атрибуты и прочую мало используемую хренотень...
Ratings: 0 negative/0 positive
Re: Узнать, упакована ли переменная
Simple777

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

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

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

произойдёт распаковка?

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

Сообщений: 2969
Дата регистрации: 24.04.2004
Simple777
После таких вопросов на собеседовании "по-хорошему" надо сообщить потенциальному работодателю, что "он (работодатель) не прошел собеседование".

Один чел рассказал, что когда он устраивался на работу Java программистом, ему задали задачу "если со всех дорог города Краснодара собрать асфальт и ссыпать в кучу - какой высоты будет куча". На работу то его приняли, но ни к чему хорошему это не привело - он уже оттуда свалил, наверное, и года не протянул.

Наверное, надо составлять список дурацких вопросов от работодателей...

Другому, кода устраивался на работу кодером C#, дали задачу

Целые числа x, y, z и k удовлетворяют равенству x2 + y2 + z2 = k2. Доказать, что число x*y*z делится на 4.

Нашёл, что это "Олимпиадные задачи по математике (7-11 класс)" www.seznaika.ru
Ratings: 0 negative/0 positive


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

On-line: 7 (Гостей: 7)

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