Question

After reading the MSDN article on the ref keyword, I am confused as to what C# does when you pass a value type using the ref keyword. The documentation states that the ValueTypes are not boxed. My question is how does C# handle passing a value type as a reference? Is it passing some copy to the data that is allocated on the Stack? Thanks.

Was it helpful?

Solution

Is it passing some copy to the data that is allocated on the Stack?

No, it does not make a copy. ref and out keyword can be compared to passing by pointer in C or passing by reference in C++, when the memory location (i.e. an address) of the variable is passed to the target method. The method that takes a reference would then modify the value directly in place using the memory location passed in.

Knowing that the variable is passed by reference, compiler inserts instructions that treat the ref variable as an address, allowing in-place modifications.

OTHER TIPS

tl;dr: Boxing isn't "how you create a reference"; it's "how you package a primitive value type for consumers who don't expect that exact type".

In .NET, reference types are class instances on the heap. Value types like int or double are just the bytes: A 32-bit int is just four bytes worth of zeroes and ones. When you put it in, say a System.List (the old-timey pre-generic kind, that Granpaw whittled out down at the General Store), then take it back out, how will the compiler know what to do if you call GetType() on it? It would just have four bytes of... what? Who knows? If it stored a pointer in the List, it would have a pointer to four bytes of... who knows?

In your own method, the generated code knows what your variable is. Regular strong type-checking. But that doesn't work when you send your variable's value it to somebody else who only knows he's expecting Object.

So when you add an int to a List, or pass it to a function that takes Object as an argument, the compiler has to add some information to it so everybody else knows what he's getting.

So "Boxing" means packaging a non-reference value into an object that can be treated as an instance of Object. For ordinary ref parameters, that's not necessary, because the type is known the whole way: The code generated for the guts of the function doesn't have to be prepared to deal with any arbitrary reference type. It knows it's getting (for example) a pointer to an integer, and that's all it's going to get. Boxing provides capability that's not required in this case, and so the compiler doesn't waste your users' cycles on it.

Boxing isn't the only way to have a reference (in the broadest sense of the term) to, for example, a double. Rather, boxing is the only way to treat a double as an object that can be stored in a System.List: It has to be on the heap, it has to be castable to Object, has to have run-time type information, etc. etc.

For the following, all all the caller or the callee need is the address of 64 zeroes and ones somewhere:

void f(ref double d) { d *= 2; }
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top