You need to be very clear on the distinction between reference types vs value types, and "by value" parameters vs "by reference" parameters.
I have articles on both topics:
The two interact somewhat when using a "by value" parameter which is a reference type: in this case the value which copied by value is the reference itself; you can still modify the object that the reference refers to:
void SomeMethod(StringBuilder x)
{
x.Append("Modified");
}
...
StringBuilder builder = new StringBuilder();
SomeMethod(builder);
Console.WriteLine(builder.ToString()); // Writes "Modified"
Note that this isn't the same thing as pass-by-reference semantics... if SomeMethod
were changed to include:
x = null;
then that wouldn't make the builder
variable null. However, if you also changed the x
parameter to be ref StringBuilder x
(and changed the calling code appropriately) then any changes to x
(such as setting it to null) would be seen by the caller.
When designing your own API, I would strongly advise you to almost never use ref
or out
parameters. They can be useful occasionally, but usually they're an indication that you're trying to return multiple values from a single method, which is often better done with a type specifically encapsulating those values, or perhaps a Tuple
type if you're using .NET 4. There are exceptions to this rule, of course, but it's a good starting point.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…