You're passing the reference to the object by value.
I.e. the address of the object is passed by value, but the address to the object and the object is the same. So when you call your method, the VM copies the reference; you're just changing a copy.
On myString.Append you're using the copied reference to get to the object (still only one object) which is then changed/invoked.
What you think you're doing is this:
class Test
{
static void Func(ref StringBuilder myString)
{
myString.Append("test");
myString = null;
}
static void Main(string[] args)
{
StringBuilder s1 = new StringBuilder();
Func(ref s1);
Console.WriteLine(s1);
}
}
A longer explanation: http://javadude.com/articles/passbyvalue.htm