Отображение значения ссылки на объект - PullRequest
2 голосов
/ 28 июля 2010

В C ++ довольно просто отобразить фактическое значение указателя на объект.Например:

void* p = new CSomething();
cout << p;

Есть ли способ сделать что-то подобное в .NET?

Ценность этого будет / может быть только образовательной, например, для демонстрации, какотображение значения, которое студенты могут видеть, а не просто сравнивать для ссылочного равенства или нуля (ничего), чтобы доказать мелкие копии, неизменность и т. д.

Ответы [ 7 ]

7 голосов
/ 28 июля 2010

Вы можете использовать GCHandle, чтобы получить адрес закрепленного объекта. ГХ может перемещать объекты, поэтому единственный разумный адрес, который нужно получить, - это один из закрепленных объектов.

GCHandle handle = GCHandle.Alloc(obj, GCHandleType.Pinned);
Console.WriteLine(handle.AddrOfPinnedObject().ToInt32());
handle.Free();

Помните, однако, что GCHandle будет закреплять только объекты примитивного или blittable типов. Некоторые объекты являются blittable (и вы можете настроить его для демонстрационных целей, чтобы он работал), но любой ссылочный тип не будет blittable.

Вам нужно будет добавить явное описание с помощью [StructLayout(LayoutKind.Sequential)] или использовать отладчик для непосредственной проверки адресов объекта, которые не соответствуют этим критериям.

6 голосов
/ 28 июля 2010

Если это для образовательных целей, я предлагаю вместо этого использовать отладчик.Если вы загружаете SOS.dll (которая является частью .NET Framework) в WinDbg или даже Visual Studio, вы можете проверить реальные объекты в памяти.

Например, для отображения кучи используйте команду !dumpheap -stat.Команда !do выводит управляемый объект по указанному адресу памяти и т. Д.SOS имеет множество команд, которые позволят вам изучить внутренние структуры .NET, поэтому это действительно полезный инструмент для получения дополнительной информации о среде выполнения.

Используя для этого отладчик, вы не ограничены в просмотре демонстрационных приложений.Вы можете заглянуть в детали реальных приложений.Кроме того, вы приобретете некоторые действительно полезные навыки отладки.

Есть несколько отличных введений в отладку с использованием WinDbg + SOS.Проверьте блог Тесс на множество учебных пособий.

3 голосов
/ 28 июля 2010

RuntimeHelpers.GetHashCode даст вам хеш-код на основе идентификации.На практике это, вероятно, основано на адресе.Как объяснено:

"RuntimeHelpers.GetHashCode полезен в сценариях, где вы заботитесь об идентичности объекта. Две строки с одинаковым содержимым будут возвращать разные значения для RuntimeHelpers.GetHashCode, поскольку они являются разными строковыми объектами, хотя ихсодержимое одинаковое. "

Стажировка строковых литералов является основным возможным исключением.Это на самом деле то же самое в C ++.

0 голосов
/ 28 июля 2010

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

В следующий раз, когда произойдет сборка мусора, адрес вашего объекта может измениться:

  • Если на объект больше не ссылаются откуда-либо, он будет собран, а некоторые другиеобъект будет занимать этот адрес
  • Если на объект все еще ссылаются, он, вероятно, будет переведен в более высокое поколение (и, следовательно, перемещен в другую кучу GC).В качестве альтернативы, если это уже поколение 2, оно, вероятно, будет перемещено в память при сжатии кучи.

Наличие сборщика мусора является причиной существования указателя int* в @ Jesper's.в объеме блока { }.Указатель фиксируется только внутри этого блока;как только выполнение покидает блок, объект получает право на сбор и / или перемещение.

0 голосов
/ 28 июля 2010
unsafe 
{
    object o = new Object(); 
    int *ptr = &o; //Get address

    Console.WriteLine((int)ptr); //Write address
}

Вам необходимо скомпилировать это с ключом / unsafe

0 голосов
/ 28 июля 2010

В .Net вы вообще не работаете с указателями. Таким образом, вы бы создали ссылочные объекты, из которых вы всегда можете увидеть значение.

При сравнении ссылочных объектов сравниваются ссылки, а не фактические значения! (За исключением сравнения строк, где '==' перегружено).

Возможно, пример .Net того, что вы хотите продемонстрировать, прояснил бы вещи ...

0 голосов
/ 28 июля 2010

Я понимаю, что если вы предоставите компилятору опцию / unsafe , вам будет разрешено писать «небезопасный» код, и с его помощью иметь доступ к указателям.

Я не проверял это, но нашел это в этой статье

Edit:

Кажется, главное, что нужно помнить, это то, что вам придется помечать любой код небезопасным кодом с помощью ключевого слова unsafe:

unsafe public static void Main()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...