When you call a method in C#, the default is to pass by value: a copy is made of the value and that it passed to the method to work with.
Nothing the method does to the variable will affect the outside world:
public void NoAffect(int x)
{
Console.WriteLine(x)
x = 0;
Console.WriteLine(x)
}
...
int myVar = 666;
NoAffect(myVar);
Console.WriteLine(myVar);
Will give you:
666
0
666
Because a copy of the
myVar
variable was made and passed the NoAffect.
This means that you can call NoAffect with a variable or a constant value:
...
int myVar = 666;
NoAffect(myVar);
Console.WriteLine(myVar);
...
NoAffect(666);
Console.WriteLine(666);
Will give you the same results.
That is the same regardless of whether the datatype passed is a Value type or a Reference type:
public class MyClass
{
public int x;
}
public void NoAffect(MyClass mc)
{
Console.WriteLine(mc.x)
mc = new MyClass{x = 0};
Console.WriteLine(mc.x)
}
...
MyClass myVar = new MyClass {x = 666};
NoAffect(myVar);
Console.WriteLine(myVar.x);
And it will print the same thing:
666
0
666
Because the reference was copied and passed to the method.
OK so far?
When you pass by reference that doesn't happen: a copy isn't passed, but an
alias is - the variable in the method is the variable outside it:
public void Affect(ref int x)
{
Console.WriteLine(x)
x = 0;
Console.WriteLine(x)
}
...
int myVar = 666;
Affect(myVar);
Console.WriteLine(ref myVar);
Will give you:
666
0
0
Again, the same thing happens with Reference types:
...
MyClass mc = new MyClass {x = 666};
Affect (ref mc);
Console.WriteLine(mc.x);
...
public void Affect(ref MyClass mc)
{
Console.WriteLine(mc.x);
mc = new MyClass{x = 0};
Console.WriteLine(mc.x);
}
Because an alias to the reference variable is passed this time.
This means that Affect cannot be called with a constant value at all - you can't pass an alias to a constant, it must be what is called an L-Value: something that can be on the "left hand side" of an assignment operator.
Technically, a reference is passed (even to a value type) but it shouldn't be confused with the "reference" in "reference type" because it's not the same thing - passing a genuine reference to a Value type variable would require boxing and unboxing and that doesn't happen with pass by reference - which is why I called it an alias above. so I'd disagree (and agree!) with both the descriptions in your question!
Does that seem a little clearer?