views:

572

answers:

3

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?

+2  A: 

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
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
To add to what Jon said, a ref parameter MUST be initialized, and out parameter doesn't have to be (but can).
Jon B
@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
Yeah I screwed up in what I was asking. I meant how are value types handled in ref/out versus by reference.
Programmin Tool
+8  A: 

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  A: 

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.

rstevens
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