-3

Objects are "passed by value" (and not "passed by reference" as some people may think) where the value is the reference. Just out of complete curiosity, is it possible to get the value of this reference? I assume this value is some sort of virtual address.

For example, is it possible to get someInstance's reference value?

    public class Program
    {
        public static void Main()
        {   
            SomeClass someInstance = new SomeClass();   
            SomeMethod(someInstance);
        }

        static void SomeMethod(SomeClass input) {
            //...
        }
    }
burnt1ce
  • 14,387
  • 33
  • 102
  • 162
  • Probably with something `unsafe`, but generally you don't need to. – crashmstr May 01 '14 at 19:35
  • 4
    What do you mean by "get"? Are you looking for a number of some kind? – Jon Skeet May 01 '14 at 19:35
  • You can get a pointer to certain (primitive) types using `unsafe` but it doesn't work for complex types. Also, the physical memory location of a .NET instance is not guaranteed to be fixed over time - objects may get moved around. Even if you acquire the physical location to an object, it's only valid as long as it's pinned (`fixed`). – xxbbcc May 01 '14 at 19:38
  • The closest thing I can think of is [`GCHandle`](http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.gchandle(v=vs.110).aspx), which is not the same as get the value of the reference. – vcsjones May 01 '14 at 19:39
  • 1
    You've not in any sense shown the problem you're trying to solve, so there's no way to know if an answer being offered will meet your requirements. – ClickRick May 01 '14 at 19:54
  • @JonSkeet Yes, I was expecting a number of some kind that represents some address. – burnt1ce May 01 '14 at 20:31
  • @ClickRick I have no problem to begin with. As I said, I'm just curious. – burnt1ce May 01 '14 at 20:33

1 Answers1

4

Objects in .NET doesn't have fixed address, since they can be moved by GC. You need to tell GC to pin it with fixed statement if you would like to get that address. Please take a look at Understanding Memory References, Pinned Objects, and Pointers

You will need to use compile in "unsafe" mode (VS Project->Properties->Build and check "Allow unsafe code")

using System;

internal class Program
{
    private static unsafe void Main(string[] args)
    {
        Point point = new Point { X = 10, Y = 20};
        long a = 1;
        long* pA = &a;

        Console.WriteLine("'a' pointer value: \t{0}", *pA);
        Console.WriteLine("'a' pointer address: \t{0:x16}", (long)pA);
        Console.WriteLine("'point' value: \t\t{0:x16}", *(pA - 1));

        // the location of 'point' on the stack
        long prP = (long)(pA - 1); 
        long* pP = *(long**)prP;
        Console.WriteLine("'point' address: \t{0:x16}", *pP);
        Console.WriteLine("'point.Y' value: \t{0}", *(pP + 1));
        Console.WriteLine("'point.X' value: \t{0}", *(pP + 2));

        Console.ReadLine();
    }
}

internal class Point
{
    public int X;
    public long Y;
}

Output:

'a' pointer value:      1
'a' pointer address:    000000001cb6dfa8
'point' value:          00000000027dd788
'point' address:        000007fe8a0851a8
'point.Y' value:        20
'point.X' value:        10
Vlad Bezden
  • 83,883
  • 25
  • 248
  • 179