4

UPDATE So totally pulled a tool moment. I really meant by reference versus Out/Ref. Anything that says 'ref' I really meant by reference as in

SomeMethod(Object someObject)

Versus

SomeMethod(out someObject)

Sorry. Just don't want to change the code so the answers already make sense.

Far as I understand, unlike ref where it "copies" the pointer and creates a new space on the stack to use that pointer, but won't change the pointer:

SomeMethod()
{
 SomeThing outer = new SomeThing();
 RefMethod(ref outer)
}

RefMethod(ref inner)  //new space on stack created and uses same pointer as outer
{
   inner.Hi = "There"; //updated the object being pointed to by outer
   inner = new SomeThing();//Given a new pointer, no longer shares pointer with outer
                           //New object on the heap
}

Out copies the pointer and can manipulate where it points to:

SomeMethod()
{
 SomeThing outer = new SomeThing();
 RefMethod(out outer)
}

RefMethod(out inner)  //same pointer shared
{

   inner = new SomeThing();//pointer now points to new place on heap  
                           //outer now points to new object
                           //Old object is orphaned if nothing else points to it
}

That's fine and dandy with objects, but what about value types seeing as they have nothing to point to being only on the stack?

trincot
  • 317,000
  • 35
  • 244
  • 286
Programmin Tool
  • 6,507
  • 11
  • 50
  • 68

3 Answers3

9

Just because the variable lives on the stack (if it's a local variable) doesn't mean you can't create a pointer to it - and indeed that's the case with reference types as well.

The pointer within RefMethod is to the "outer" variable - and the variable itself lives on the stack as it's an uncaptured local variable.

As Leppie said, ref and out are identical except for the rules on definite assignment - in fact, the only difference in IL is an attribute applied to out parameters.

See my article on parameter passing for more details about ref/out in general.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
3

ref and out is exactly the same, as far I know, with the exception that an out parameter cannot be initialized. Hence both goes on the stack.

leppie
  • 115,091
  • 17
  • 196
  • 297
  • I think you mean an out parameter *has* to be definitely assigned before a normal return within the method; a variable used as an out argument doesn't have to be definitely assigned before the call, although it can be. (It will be afterwards.) – Jon Skeet Jan 12 '09 at 19:53
  • To add to what Jon said, a ref parameter MUST be initialized, and out parameter doesn't have to be (but can). – Jon B Jan 12 '09 at 19:56
  • @JonB: You mean "argument" for both of these. Important distinction in this particular case :) (The argument is on the calling side; the parameter is specified on the called side.) – Jon Skeet Jan 12 '09 at 20:22
  • Yeah I screwed up in what I was asking. I meant how are value types handled in ref/out versus by reference. – Programmin Tool Jan 12 '09 at 20:44
1

Actually using ref or out on Reference types also creates a pointer...not to the object but to the reference to the object! So it would be some kind of

RefMethod(SomeThing **inner)
{
}

in C++, while with value types it would be

RefMethod2(int *inner)
{
}

for value types.

mmmmmmmm
  • 15,269
  • 2
  • 30
  • 55
  • To my mind it's clearer to say that ref creates a pointer to the *variable* (whose value is indeed the reference to the object). Just MHO though. – Jon Skeet Jan 12 '09 at 20:45