Help greatly appreciated
Your understanding will be improved by a correct and careful use of language.
Passing by value means a copy of an argument is passed.
Yes, this is exactly accurate.
Changes to that copy do not change the original.
Not exactly. Begin by carefully distinguishing between values and variables. Consider:
class Foo { public int x; }
...
void N()
{
Foo blah = new Foo();
blah.x = 0;
M(blah);
}
...
void M(Foo foo)
{
foo.x = 123; // changes blah.x
foo = null; // does not change blah
}
The variables here are x, blah and foo. x is a field, blah is a local, foo is a formal parameter.
The values here are null, 0, 123, and a reference to an instance of Foo. That reference is a value. It is crucial to understand this fact.
A copy of the value of blah is passed by copying the value of variable blah into variable foo. The value of blah is a reference to the instance of Foo.
M can change the value of variable x because M has a copy of the value of blah, which is a reference to a Foo. When M changes the contents of foo to null, that does not change blah; foo contains a copy of the value of blah.
Passing by reference means a reference to the original is passed.
Choose your wording carefully. What is "the original"?
This would be better stated as "passing by reference means that a reference to the argument, which must be a variable, is passed". An easier way to think about it is that "passing by reference makes the parameter an alias for the variable passed as the argument".
changes to the reference affect the original.
Since the parameter and the argument are aliases for each other, it's not that changes to the reference affect the original; the reference IS the original. They are both the same variable.
REF tells the compiler that the object is initialized before entering the function.
"The object" is meaningless. You mean "the variable".
"ref" does not "tell the compiler that the variable is initialized". Rather, "ref" tells the compiler "you, compiler, must verify that the variable is initialized". That is rather different!
REF means the value is already set,
No, ref requires that the variable is already set. There's no such thing as "setting a value".
the method can therefore read it and modify it.
Where by "it" you mean "the variable".
REF is two ways, both in and out.
Correct.
OUT tells the compiler that the object will be intialized inside the function.
Stop using "the object" to mean "the variable". You will understand things much more clearly if you stop confusing completely different things. Variables are not objects. Variables are storage locations some of which might contain values, and some of those values might be references to objects.
So, out tells the compiler that the variable will be initialized inside the method, yes, but that's not quite right. You are forgetting about the cases where the method will throw an exception, or the method will go into an infinite loop -- those are also legal scenarios.
OUT means the value is not already set,
Again, by "the value", you mean "the variable". But this is not accurate. It is perfectly legal to pass an initialized variable as an "out" parameter. Pointless, but legal.
and therefore must be set before calling return.
"return" is not called; methods are called. But yes, the method must assign a value to the variable before returning normally.
OUT is only one way, which is out.
Right.
So in what scenarios would you combine the use of the ref and out keywords
There are no such scenarios.
ref
andout
on the same argument. And both of those keywords are used for passing by reference. – Madlynmadmanref
keyword is only useful on pass-by-value defaulted values such as structs, ints, floats, bools, and enums. – Definitive