This is an programmatic anlaysis of Value types and Reference types passed by value and reference with newing the object inside the method. Read the conclusions for a clear cut understanding of this apparent confusing funda.
//Value types 'pass by' analysis.
// 1. Pass by reference, new obj inside the method.
string str = "abc";
modifyStr1(ref str);
MessageBox.Show(str); // outputs "x"
// 2. Pass by reference, no new obj inside the method.
str = "abc";
modifyStr2(ref str);
MessageBox.Show(str);// outputs "x"
// 3. Pass by value, new obj inside the method
str = "abc";
modifyStr3(str);
MessageBox.Show(str);// outputs "abc"
// 4. Pass by value, no new obj inside the method
str = "abc";
modifyStr4(str);
MessageBox.Show(str);// outputs "abc"
// Conclusion:
// 1. Value types have to be passed as ref,
// if you need the value back.
// 2. It doesn't matter even if the value types
// are newed inside the method.
// It still returns the value back.
//Reference types 'pass by' analysis.
// 1. Pass by reference, new obj inside the method.
ReferenceClass myObj = new ReferenceClass();
myObj.myVar = 10;
modifyObj1(ref myObj);
MessageBox.Show(myObj.myVar.ToString()); // Outputs "20"
// 2. Pass by reference, no new obj inside the method.
// Directly assign value to member variable.
myObj.myVar = 10;
modifyObj2(ref myObj);
MessageBox.Show(myObj.myVar.ToString()); // Outputs "20"
// 3. Pass by value, new obj inside the method.
myObj.myVar = 10;
modifyObj3(myObj);
MessageBox.Show(myObj.myVar.ToString()); // Outputs "10"
// 4. Pass by value, no new obj inside the method.
myObj.myVar = 10;
modifyObj4(myObj);
MessageBox.Show(myObj.myVar.ToString()); // Outputs "20"
// Conclusion:
// 1. Reference types needn't be passed as ref,
// if you need the value back, provided that you make
// sure the same object is not newed inside the method.
// 2. Pass them as ref, if you need the value back,
// and dont bother if someone news it inside
// the method or not.