In order for something to be passed by reference, the declared type of the parameter must exactly match the declared type of the thing being passed. Boxing only happens when the type of the value is converted to something whose declared type is not the type of value, and therefore is not exactly the same as the type of value in question.
Some people may not like variable value types, but passing variable value types by reference often exceeds the evil practice of passing messy links. For example, consider:
struct StructType1 {public int V; ...}
class ClassType1 {public int V; ...}
void blah ()
{
StructType1 s1;
ClassType1 c1 = new ClassType1 ();
... do some stuff ...
Routine1 (s_pt, c_pt);
Routine2 (ref s_pt, ref c_pt);
... do more stuff
}
What effect can Routine1 have on S1.V? What effect can Procedure 1 have on C1.V?
What effect can Routine2 have on S1.V? When can such effects occur? What about C1.V? In particular, is there any way to find out if Routine1 or Routine2 can cause C1.V to change at any arbitrary time in the future, long after the call returns?
Also, suppose S1 contains some data that I want to store in the class. If S1 contains nothing but value types (which may or may not be mutable) and immutable reference types, do I need to worry about anything unexpectedly changing the data that I stored there?
Now suppose it was C1, which stores the data that I wanted to save. If C1 is modified or contains any mutable reference types, and I set it to some external functions, is there any way to safely store the information contained in it without knowing about a sufficient amount of C1 internals?
Passing structures by reference is a great way to allow other functions to provide multiple pieces of information without excessive copying. Support for mutable value types can be a nuisance for language developers, but the semantics of values ββare very useful in production code, despite some unsuccessful quirks in implementing some frameworks.